]> granicus.if.org Git - icinga2/blob - lib/config/expression.hpp
Merge pull request #7113 from Elias481/fix/incorrect-usage-of-global-namespace-6874...
[icinga2] / lib / config / expression.hpp
1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2
3 #ifndef EXPRESSION_H
4 #define EXPRESSION_H
5
6 #include "config/i2-config.hpp"
7 #include "base/debuginfo.hpp"
8 #include "base/array.hpp"
9 #include "base/dictionary.hpp"
10 #include "base/function.hpp"
11 #include "base/exception.hpp"
12 #include "base/scriptframe.hpp"
13 #include "base/convert.hpp"
14 #include <map>
15
16 namespace icinga
17 {
18
19 struct DebugHint
20 {
21 public:
22         DebugHint(Dictionary::Ptr hints = nullptr)
23                 : m_Hints(std::move(hints))
24         { }
25
26         DebugHint(Dictionary::Ptr&& hints)
27                 : m_Hints(std::move(hints))
28         { }
29
30         void AddMessage(const String& message, const DebugInfo& di)
31         {
32                 GetMessages()->Add(new Array({ message, di.Path, di.FirstLine, di.FirstColumn, di.LastLine, di.LastColumn }));
33         }
34
35         DebugHint GetChild(const String& name)
36         {
37                 const Dictionary::Ptr& children = GetChildren();
38
39                 Value vchild;
40                 Dictionary::Ptr child;
41
42                 if (!children->Get(name, &vchild)) {
43                         child = new Dictionary();
44                         children->Set(name, child);
45                 } else
46                         child = vchild;
47
48                 return DebugHint(child);
49         }
50
51         Dictionary::Ptr ToDictionary() const
52         {
53                 return m_Hints;
54         }
55
56 private:
57         Dictionary::Ptr m_Hints;
58         Array::Ptr m_Messages;
59         Dictionary::Ptr m_Children;
60
61         const Array::Ptr& GetMessages()
62         {
63                 if (m_Messages)
64                         return m_Messages;
65
66                 if (!m_Hints)
67                         m_Hints = new Dictionary();
68
69                 Value vmessages;
70
71                 if (!m_Hints->Get("messages", &vmessages)) {
72                         m_Messages = new Array();
73                         m_Hints->Set("messages", m_Messages);
74                 } else
75                         m_Messages = vmessages;
76
77                 return m_Messages;
78         }
79
80         const Dictionary::Ptr& GetChildren()
81         {
82                 if (m_Children)
83                         return m_Children;
84
85                 if (!m_Hints)
86                         m_Hints = new Dictionary();
87
88                 Value vchildren;
89
90                 if (!m_Hints->Get("properties", &vchildren)) {
91                         m_Children = new Dictionary();
92                         m_Hints->Set("properties", m_Children);
93                 } else
94                         m_Children = vchildren;
95
96                 return m_Children;
97         }
98 };
99
100 enum CombinedSetOp
101 {
102         OpSetLiteral,
103         OpSetAdd,
104         OpSetSubtract,
105         OpSetMultiply,
106         OpSetDivide,
107         OpSetModulo,
108         OpSetXor,
109         OpSetBinaryAnd,
110         OpSetBinaryOr
111 };
112
113 enum ScopeSpecifier
114 {
115         ScopeLocal,
116         ScopeThis,
117         ScopeGlobal
118 };
119
120 typedef std::map<String, String> DefinitionMap;
121
122 /**
123  * @ingroup config
124  */
125 enum ExpressionResultCode
126 {
127         ResultOK,
128         ResultReturn,
129         ResultContinue,
130         ResultBreak
131 };
132
133 /**
134  * @ingroup config
135  */
136 struct ExpressionResult
137 {
138 public:
139         template<typename T>
140         ExpressionResult(T value, ExpressionResultCode code = ResultOK)
141                 : m_Value(std::move(value)), m_Code(code)
142         { }
143
144         operator const Value&() const
145         {
146                 return m_Value;
147         }
148
149         const Value& GetValue() const
150         {
151                 return m_Value;
152         }
153
154         ExpressionResultCode GetCode() const
155         {
156                 return m_Code;
157         }
158
159 private:
160         Value m_Value;
161         ExpressionResultCode m_Code;
162 };
163
164 #define CHECK_RESULT(res)                       \
165         do {                                    \
166                 if (res.GetCode() != ResultOK)  \
167                         return res;             \
168         } while (0);
169
170 #define CHECK_RESULT_LOOP(res)                  \
171         if (res.GetCode() == ResultReturn)      \
172                 return res;                     \
173         if (res.GetCode() == ResultContinue)    \
174                 continue;                       \
175         if (res.GetCode() == ResultBreak)       \
176                 break;                          \
177
178 /**
179  * @ingroup config
180  */
181 class Expression
182 {
183 public:
184         Expression() = default;
185         Expression(const Expression&) = delete;
186         virtual ~Expression();
187
188         Expression& operator=(const Expression&) = delete;
189
190         ExpressionResult Evaluate(ScriptFrame& frame, DebugHint *dhint = nullptr) const;
191         virtual bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint = nullptr) const;
192         virtual const DebugInfo& GetDebugInfo() const;
193
194         virtual ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const = 0;
195
196         static boost::signals2::signal<void (ScriptFrame& frame, ScriptError *ex, const DebugInfo& di)> OnBreakpoint;
197
198         static void ScriptBreakpoint(ScriptFrame& frame, ScriptError *ex, const DebugInfo& di);
199 };
200
201 std::unique_ptr<Expression> MakeIndexer(ScopeSpecifier scopeSpec, const String& index);
202
203 class OwnedExpression final : public Expression
204 {
205 public:
206         OwnedExpression(std::shared_ptr<Expression> expression)
207                 : m_Expression(std::move(expression))
208         { }
209
210 protected:
211         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override
212         {
213                 return m_Expression->DoEvaluate(frame, dhint);
214         }
215
216         const DebugInfo& GetDebugInfo() const override
217         {
218                 return m_Expression->GetDebugInfo();
219         }
220
221 private:
222         std::shared_ptr<Expression> m_Expression;
223 };
224
225 class LiteralExpression final : public Expression
226 {
227 public:
228         LiteralExpression(Value value = Value());
229
230         const Value& GetValue() const
231         {
232                 return m_Value;
233         }
234
235 protected:
236         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
237
238 private:
239         Value m_Value;
240 };
241
242 inline LiteralExpression *MakeLiteralRaw(const Value& literal = Value())
243 {
244         return new LiteralExpression(literal);
245 }
246
247 inline std::unique_ptr<LiteralExpression> MakeLiteral(const Value& literal = Value())
248 {
249         return std::unique_ptr<LiteralExpression>(MakeLiteralRaw(literal));
250 }
251
252 class DebuggableExpression : public Expression
253 {
254 public:
255         DebuggableExpression(DebugInfo debugInfo = DebugInfo())
256                 : m_DebugInfo(std::move(debugInfo))
257         { }
258
259 protected:
260         const DebugInfo& GetDebugInfo() const final;
261
262         DebugInfo m_DebugInfo;
263 };
264
265 class UnaryExpression : public DebuggableExpression
266 {
267 public:
268         UnaryExpression(std::unique_ptr<Expression> operand, const DebugInfo& debugInfo = DebugInfo())
269                 : DebuggableExpression(debugInfo), m_Operand(std::move(operand))
270         { }
271
272 protected:
273         std::unique_ptr<Expression> m_Operand;
274 };
275
276 class BinaryExpression : public DebuggableExpression
277 {
278 public:
279         BinaryExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
280                 : DebuggableExpression(debugInfo), m_Operand1(std::move(operand1)), m_Operand2(std::move(operand2))
281         { }
282
283 protected:
284         std::unique_ptr<Expression> m_Operand1;
285         std::unique_ptr<Expression> m_Operand2;
286 };
287
288 class VariableExpression final : public DebuggableExpression
289 {
290 public:
291         VariableExpression(String variable, std::vector<std::shared_ptr<Expression> > imports, const DebugInfo& debugInfo = DebugInfo());
292
293         String GetVariable() const
294         {
295                 return m_Variable;
296         }
297
298 protected:
299         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
300         bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const override;
301
302 private:
303         String m_Variable;
304         std::vector<std::shared_ptr<Expression> > m_Imports;
305
306         friend void BindToScope(std::unique_ptr<Expression>& expr, ScopeSpecifier scopeSpec);
307 };
308
309 class DerefExpression final : public UnaryExpression
310 {
311 public:
312         DerefExpression(std::unique_ptr<Expression> operand, const DebugInfo& debugInfo = DebugInfo())
313                 : UnaryExpression(std::move(operand), debugInfo)
314         { }
315
316 protected:
317         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
318         bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const override;
319 };
320
321 class RefExpression final : public UnaryExpression
322 {
323 public:
324         RefExpression(std::unique_ptr<Expression> operand, const DebugInfo& debugInfo = DebugInfo())
325                 : UnaryExpression(std::move(operand), debugInfo)
326         { }
327
328 protected:
329         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
330 };
331
332 class NegateExpression final : public UnaryExpression
333 {
334 public:
335         NegateExpression(std::unique_ptr<Expression> operand, const DebugInfo& debugInfo = DebugInfo())
336                 : UnaryExpression(std::move(operand), debugInfo)
337         { }
338
339 protected:
340         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
341 };
342
343 class LogicalNegateExpression final : public UnaryExpression
344 {
345 public:
346         LogicalNegateExpression(std::unique_ptr<Expression> operand, const DebugInfo& debugInfo = DebugInfo())
347                 : UnaryExpression(std::move(operand), debugInfo)
348         { }
349
350 protected:
351         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
352 };
353
354 class AddExpression final : public BinaryExpression
355 {
356 public:
357         AddExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
358                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
359         { }
360
361 protected:
362         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
363 };
364
365 class SubtractExpression final : public BinaryExpression
366 {
367 public:
368         SubtractExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
369                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
370         { }
371
372 protected:
373         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
374 };
375
376 class MultiplyExpression final : public BinaryExpression
377 {
378 public:
379         MultiplyExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
380                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
381         { }
382
383 protected:
384         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
385 };
386
387 class DivideExpression final : public BinaryExpression
388 {
389 public:
390         DivideExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
391                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
392         { }
393
394 protected:
395         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
396 };
397
398 class ModuloExpression final : public BinaryExpression
399 {
400 public:
401         ModuloExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
402                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
403         { }
404
405 protected:
406         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
407 };
408
409 class XorExpression final : public BinaryExpression
410 {
411 public:
412         XorExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
413                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
414         { }
415
416 protected:
417         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
418 };
419
420 class BinaryAndExpression final : public BinaryExpression
421 {
422 public:
423         BinaryAndExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
424                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
425         { }
426
427 protected:
428         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
429 };
430
431 class BinaryOrExpression final : public BinaryExpression
432 {
433 public:
434         BinaryOrExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
435                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
436         { }
437
438 protected:
439         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
440 };
441
442 class ShiftLeftExpression final : public BinaryExpression
443 {
444 public:
445         ShiftLeftExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
446                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
447         { }
448
449 protected:
450         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
451 };
452
453 class ShiftRightExpression final : public BinaryExpression
454 {
455 public:
456         ShiftRightExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
457                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
458         { }
459
460 protected:
461         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
462 };
463
464 class EqualExpression final : public BinaryExpression
465 {
466 public:
467         EqualExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
468                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
469         { }
470
471 protected:
472         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
473 };
474
475 class NotEqualExpression final : public BinaryExpression
476 {
477 public:
478         NotEqualExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
479                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
480         { }
481
482 protected:
483         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
484 };
485
486 class LessThanExpression final : public BinaryExpression
487 {
488 public:
489         LessThanExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
490                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
491         { }
492
493 protected:
494         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
495 };
496
497 class GreaterThanExpression final : public BinaryExpression
498 {
499 public:
500         GreaterThanExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
501                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
502         { }
503
504 protected:
505         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
506 };
507
508 class LessThanOrEqualExpression final : public BinaryExpression
509 {
510 public:
511         LessThanOrEqualExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
512                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
513         { }
514
515 protected:
516         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
517 };
518
519 class GreaterThanOrEqualExpression final : public BinaryExpression
520 {
521 public:
522         GreaterThanOrEqualExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
523                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
524         { }
525
526 protected:
527         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
528 };
529
530 class InExpression final : public BinaryExpression
531 {
532 public:
533         InExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
534                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
535         { }
536
537 protected:
538         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
539 };
540
541 class NotInExpression final : public BinaryExpression
542 {
543 public:
544         NotInExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
545                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
546         { }
547
548 protected:
549         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
550 };
551
552 class LogicalAndExpression final : public BinaryExpression
553 {
554 public:
555         LogicalAndExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
556                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
557         { }
558
559 protected:
560         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
561 };
562
563 class LogicalOrExpression final : public BinaryExpression
564 {
565 public:
566         LogicalOrExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
567                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
568         { }
569
570 protected:
571         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
572 };
573
574 class FunctionCallExpression final : public DebuggableExpression
575 {
576 public:
577         FunctionCallExpression(std::unique_ptr<Expression> fname, std::vector<std::unique_ptr<Expression> >&& args, const DebugInfo& debugInfo = DebugInfo())
578                 : DebuggableExpression(debugInfo), m_FName(std::move(fname)), m_Args(std::move(args))
579         { }
580
581 protected:
582         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
583
584 public:
585         std::unique_ptr<Expression> m_FName;
586         std::vector<std::unique_ptr<Expression> > m_Args;
587 };
588
589 class ArrayExpression final : public DebuggableExpression
590 {
591 public:
592         ArrayExpression(std::vector<std::unique_ptr<Expression > >&& expressions, const DebugInfo& debugInfo = DebugInfo())
593                 : DebuggableExpression(debugInfo), m_Expressions(std::move(expressions))
594         { }
595
596 protected:
597         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
598
599 private:
600         std::vector<std::unique_ptr<Expression> > m_Expressions;
601 };
602
603 class DictExpression final : public DebuggableExpression
604 {
605 public:
606         DictExpression(std::vector<std::unique_ptr<Expression> >&& expressions = {}, const DebugInfo& debugInfo = DebugInfo())
607                 : DebuggableExpression(debugInfo), m_Expressions(std::move(expressions))
608         { }
609
610         void MakeInline();
611
612 protected:
613         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
614
615 private:
616         std::vector<std::unique_ptr<Expression> > m_Expressions;
617         bool m_Inline{false};
618
619         friend void BindToScope(std::unique_ptr<Expression>& expr, ScopeSpecifier scopeSpec);
620 };
621
622 class SetConstExpression final : public UnaryExpression
623 {
624 public:
625         SetConstExpression(const String& name, std::unique_ptr<Expression> operand, const DebugInfo& debugInfo = DebugInfo())
626                 : UnaryExpression(std::move(operand), debugInfo), m_Name(name)
627         { }
628
629 protected:
630         String m_Name;
631
632         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
633 };
634
635 class SetExpression final : public BinaryExpression
636 {
637 public:
638         SetExpression(std::unique_ptr<Expression> operand1, CombinedSetOp op, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
639                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo), m_Op(op)
640         { }
641
642         void SetOverrideFrozen();
643
644 protected:
645         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
646
647 private:
648         CombinedSetOp m_Op;
649         bool m_OverrideFrozen{false};
650
651         friend void BindToScope(std::unique_ptr<Expression>& expr, ScopeSpecifier scopeSpec);
652 };
653
654 class ConditionalExpression final : public DebuggableExpression
655 {
656 public:
657         ConditionalExpression(std::unique_ptr<Expression> condition, std::unique_ptr<Expression> true_branch, std::unique_ptr<Expression> false_branch, const DebugInfo& debugInfo = DebugInfo())
658                 : DebuggableExpression(debugInfo), m_Condition(std::move(condition)), m_TrueBranch(std::move(true_branch)), m_FalseBranch(std::move(false_branch))
659         { }
660
661 protected:
662         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
663
664 private:
665         std::unique_ptr<Expression> m_Condition;
666         std::unique_ptr<Expression> m_TrueBranch;
667         std::unique_ptr<Expression> m_FalseBranch;
668 };
669
670 class WhileExpression final : public DebuggableExpression
671 {
672 public:
673         WhileExpression(std::unique_ptr<Expression> condition, std::unique_ptr<Expression> loop_body, const DebugInfo& debugInfo = DebugInfo())
674                 : DebuggableExpression(debugInfo), m_Condition(std::move(condition)), m_LoopBody(std::move(loop_body))
675         { }
676
677 protected:
678         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
679
680 private:
681         std::unique_ptr<Expression> m_Condition;
682         std::unique_ptr<Expression> m_LoopBody;
683 };
684
685
686 class ReturnExpression final : public UnaryExpression
687 {
688 public:
689         ReturnExpression(std::unique_ptr<Expression> expression, const DebugInfo& debugInfo = DebugInfo())
690                 : UnaryExpression(std::move(expression), debugInfo)
691         { }
692
693 protected:
694         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
695 };
696
697 class BreakExpression final : public DebuggableExpression
698 {
699 public:
700         BreakExpression(const DebugInfo& debugInfo = DebugInfo())
701                 : DebuggableExpression(debugInfo)
702         { }
703
704 protected:
705         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
706 };
707
708 class ContinueExpression final : public DebuggableExpression
709 {
710 public:
711         ContinueExpression(const DebugInfo& debugInfo = DebugInfo())
712                 : DebuggableExpression(debugInfo)
713         { }
714
715 protected:
716         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
717 };
718
719 class GetScopeExpression final : public Expression
720 {
721 public:
722         GetScopeExpression(ScopeSpecifier scopeSpec)
723                 : m_ScopeSpec(scopeSpec)
724         { }
725
726 protected:
727         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
728
729 private:
730         ScopeSpecifier m_ScopeSpec;
731 };
732
733 class IndexerExpression final : public BinaryExpression
734 {
735 public:
736         IndexerExpression(std::unique_ptr<Expression> operand1, std::unique_ptr<Expression> operand2, const DebugInfo& debugInfo = DebugInfo())
737                 : BinaryExpression(std::move(operand1), std::move(operand2), debugInfo)
738         { }
739
740         void SetOverrideFrozen();
741
742 protected:
743         bool m_OverrideFrozen{false};
744
745         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
746         bool GetReference(ScriptFrame& frame, bool init_dict, Value *parent, String *index, DebugHint **dhint) const override;
747
748         friend void BindToScope(std::unique_ptr<Expression>& expr, ScopeSpecifier scopeSpec);
749 };
750
751 void BindToScope(std::unique_ptr<Expression>& expr, ScopeSpecifier scopeSpec);
752
753 class ThrowExpression final : public DebuggableExpression
754 {
755 public:
756         ThrowExpression(std::unique_ptr<Expression> message, bool incompleteExpr, const DebugInfo& debugInfo = DebugInfo())
757                 : DebuggableExpression(debugInfo), m_Message(std::move(message)), m_IncompleteExpr(incompleteExpr)
758         { }
759
760 protected:
761         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
762
763 private:
764         std::unique_ptr<Expression> m_Message;
765         bool m_IncompleteExpr;
766 };
767
768 class ImportExpression final : public DebuggableExpression
769 {
770 public:
771         ImportExpression(std::unique_ptr<Expression> name, const DebugInfo& debugInfo = DebugInfo())
772                 : DebuggableExpression(debugInfo), m_Name(std::move(name))
773         { }
774
775 protected:
776         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
777
778 private:
779         std::unique_ptr<Expression> m_Name;
780 };
781
782 class ImportDefaultTemplatesExpression final : public DebuggableExpression
783 {
784 public:
785         ImportDefaultTemplatesExpression(const DebugInfo& debugInfo = DebugInfo())
786                 : DebuggableExpression(debugInfo)
787         { }
788
789 protected:
790         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
791 };
792
793 class FunctionExpression final : public DebuggableExpression
794 {
795 public:
796         FunctionExpression(String name, std::vector<String> args,
797                 std::map<String, std::unique_ptr<Expression> >&& closedVars, std::unique_ptr<Expression> expression, const DebugInfo& debugInfo = DebugInfo())
798                 : DebuggableExpression(debugInfo), m_Name(std::move(name)), m_Args(std::move(args)), m_ClosedVars(std::move(closedVars)), m_Expression(std::move(expression))
799         { }
800
801 protected:
802         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
803
804 private:
805         String m_Name;
806         std::vector<String> m_Args;
807         std::map<String, std::unique_ptr<Expression> > m_ClosedVars;
808         std::shared_ptr<Expression> m_Expression;
809 };
810
811 class ApplyExpression final : public DebuggableExpression
812 {
813 public:
814         ApplyExpression(String type, String target, std::unique_ptr<Expression> name,
815                 std::unique_ptr<Expression> filter, String package, String fkvar, String fvvar,
816                 std::unique_ptr<Expression> fterm, std::map<String, std::unique_ptr<Expression> >&& closedVars, bool ignoreOnError,
817                 std::unique_ptr<Expression> expression, const DebugInfo& debugInfo = DebugInfo())
818                 : DebuggableExpression(debugInfo), m_Type(std::move(type)), m_Target(std::move(target)),
819                         m_Name(std::move(name)), m_Filter(std::move(filter)), m_Package(std::move(package)), m_FKVar(std::move(fkvar)), m_FVVar(std::move(fvvar)),
820                         m_FTerm(std::move(fterm)), m_IgnoreOnError(ignoreOnError), m_ClosedVars(std::move(closedVars)),
821                         m_Expression(std::move(expression))
822         { }
823
824 protected:
825         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
826
827 private:
828         String m_Type;
829         String m_Target;
830         std::unique_ptr<Expression> m_Name;
831         std::shared_ptr<Expression> m_Filter;
832         String m_Package;
833         String m_FKVar;
834         String m_FVVar;
835         std::shared_ptr<Expression> m_FTerm;
836         bool m_IgnoreOnError;
837         std::map<String, std::unique_ptr<Expression> > m_ClosedVars;
838         std::shared_ptr<Expression> m_Expression;
839 };
840
841 class NamespaceExpression final : public DebuggableExpression
842 {
843 public:
844         NamespaceExpression(std::unique_ptr<Expression> expression, const DebugInfo& debugInfo = DebugInfo())
845                 : DebuggableExpression(debugInfo), m_Expression(std::move(expression))
846         { }
847
848 protected:
849         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
850
851 private:
852         std::shared_ptr<Expression> m_Expression;
853 };
854
855 class ObjectExpression final : public DebuggableExpression
856 {
857 public:
858         ObjectExpression(bool abstract, std::unique_ptr<Expression> type, std::unique_ptr<Expression> name, std::unique_ptr<Expression> filter,
859                 String zone, String package, std::map<String, std::unique_ptr<Expression> >&& closedVars,
860                 bool defaultTmpl, bool ignoreOnError, std::unique_ptr<Expression> expression, const DebugInfo& debugInfo = DebugInfo())
861                 : DebuggableExpression(debugInfo), m_Abstract(abstract), m_Type(std::move(type)),
862                 m_Name(std::move(name)), m_Filter(std::move(filter)), m_Zone(std::move(zone)), m_Package(std::move(package)), m_DefaultTmpl(defaultTmpl),
863                 m_IgnoreOnError(ignoreOnError), m_ClosedVars(std::move(closedVars)), m_Expression(std::move(expression))
864         { }
865
866 protected:
867         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
868
869 private:
870         bool m_Abstract;
871         std::unique_ptr<Expression> m_Type;
872         std::unique_ptr<Expression> m_Name;
873         std::shared_ptr<Expression> m_Filter;
874         String m_Zone;
875         String m_Package;
876         bool m_DefaultTmpl;
877         bool m_IgnoreOnError;
878         std::map<String, std::unique_ptr<Expression> > m_ClosedVars;
879         std::shared_ptr<Expression> m_Expression;
880 };
881
882 class ForExpression final : public DebuggableExpression
883 {
884 public:
885         ForExpression(String fkvar, String fvvar, std::unique_ptr<Expression> value, std::unique_ptr<Expression> expression, const DebugInfo& debugInfo = DebugInfo())
886                 : DebuggableExpression(debugInfo), m_FKVar(std::move(fkvar)), m_FVVar(std::move(fvvar)), m_Value(std::move(value)), m_Expression(std::move(expression))
887         { }
888
889 protected:
890         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
891
892 private:
893         String m_FKVar;
894         String m_FVVar;
895         std::unique_ptr<Expression> m_Value;
896         std::unique_ptr<Expression> m_Expression;
897 };
898
899 class LibraryExpression final : public UnaryExpression
900 {
901 public:
902         LibraryExpression(std::unique_ptr<Expression> expression, const DebugInfo& debugInfo = DebugInfo())
903                 : UnaryExpression(std::move(expression), debugInfo)
904         { }
905
906 protected:
907         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
908 };
909
910 enum IncludeType
911 {
912         IncludeRegular,
913         IncludeRecursive,
914         IncludeZones
915 };
916
917 class IncludeExpression final : public DebuggableExpression
918 {
919 public:
920         IncludeExpression(String relativeBase, std::unique_ptr<Expression> path, std::unique_ptr<Expression> pattern, std::unique_ptr<Expression> name,
921                 IncludeType type, bool searchIncludes, String zone, String package, const DebugInfo& debugInfo = DebugInfo())
922                 : DebuggableExpression(debugInfo), m_RelativeBase(std::move(relativeBase)), m_Path(std::move(path)), m_Pattern(std::move(pattern)),
923                 m_Name(std::move(name)), m_Type(type), m_SearchIncludes(searchIncludes), m_Zone(std::move(zone)), m_Package(std::move(package))
924         { }
925
926 protected:
927         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
928
929 private:
930         String m_RelativeBase;
931         std::unique_ptr<Expression> m_Path;
932         std::unique_ptr<Expression> m_Pattern;
933         std::unique_ptr<Expression> m_Name;
934         IncludeType m_Type;
935         bool m_SearchIncludes;
936         String m_Zone;
937         String m_Package;
938 };
939
940 class BreakpointExpression final : public DebuggableExpression
941 {
942 public:
943         BreakpointExpression(const DebugInfo& debugInfo = DebugInfo())
944                 : DebuggableExpression(debugInfo)
945         { }
946
947 protected:
948         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
949 };
950
951 class TryExceptExpression final : public DebuggableExpression
952 {
953 public:
954         TryExceptExpression(std::unique_ptr<Expression> tryBody, std::unique_ptr<Expression> exceptBody, const DebugInfo& debugInfo = DebugInfo())
955                 : DebuggableExpression(debugInfo), m_TryBody(std::move(tryBody)), m_ExceptBody(std::move(exceptBody))
956         { }
957
958 protected:
959         ExpressionResult DoEvaluate(ScriptFrame& frame, DebugHint *dhint) const override;
960
961 private:
962         std::unique_ptr<Expression> m_TryBody;
963         std::unique_ptr<Expression> m_ExceptBody;
964 };
965
966 }
967
968 #endif /* EXPRESSION_H */