KJS

nodes.h
1 /*
2  * This file is part of the KDE libraries
3  * Copyright (C) 1999-2000 Harri Porten ([email protected])
4  * Copyright (C) 2001 Peter Kelly ([email protected])
5  * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
6  * Copyright (C) 2007, 2008 Maksim Orlovich ([email protected])
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB. If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  *
23  */
24 
25 #ifndef NODES_H_
26 #define NODES_H_
27 
28 #include "Parser.h"
29 #include "internal.h"
30 #include "CompileState.h"
31 #include "operations.h"
32 #include "SymbolTable.h"
33 #include "opcodes.h"
34 #include "bytecode/opargs.h"
35 #include <wtf/ListRefPtr.h>
36 #include <wtf/Vector.h>
37 
38 namespace KJS
39 {
40 class ProgramNode;
41 class PropertyNameNode;
42 class PropertyListNode;
43 class RegExp;
44 class SourceElementsNode;
45 class SourceStream;
46 class PackageObject;
47 class FuncDeclNode;
48 class FunctionBodyNode;
49 class Node;
50 
51 class VarDeclVisitor;
52 class FuncDeclVisitor;
53 
54 class CompileState;
55 struct CompileReference;
56 
57 class NodeVisitor
58 {
59 public:
60  virtual ~NodeVisitor() {}
61  /**
62  This method should be overridden by subclasses to process nodes, and
63  perhaps return pointers for replacement nodes. If the node should not be
64  changed, return 0. Otherwise, return the replacement node.
65 
66  The default implementation asks the node to visit its kids, and do
67  replacements on them if needed, but does not change anything for this node
68  */
69  virtual Node *visit(Node *node);
70 };
71 
72 class Node
73 {
74 public:
75  enum NodeType {
76  UnknownNodeType,
77  NullNodeType,
78  BooleanNodeType,
79  NumberNodeType,
80  StringNodeType,
81  RegExpNodeType,
82  TryNodeType,
83  GroupNodeType,
84  LabelNodeType
85  };
86 
87  Node();
88  virtual ~Node();
89 
90  virtual NodeType type() const
91  {
92  return UnknownNodeType;
93  }
94 
95  UString toString() const;
96 
97  // This updates line numbers to the pretty-printed version, and
98  // returns it out.
99  UString reindent(int baseLine = 0) const;
100 
101  virtual void streamTo(SourceStream &) const = 0;
102  int lineNo() const
103  {
104  return m_line;
105  }
106 
107  void ref();
108  void deref();
109  unsigned refcount();
110  static void clearNewNodes();
111 
112  virtual Node *nodeInsideAllParens();
113 
114  virtual bool isLocation() const
115  {
116  return false;
117  }
118  virtual bool isVarAccessNode() const
119  {
120  return false;
121  }
122  bool isNumber() const
123  {
124  return type() == NumberNodeType;
125  }
126  bool isString() const
127  {
128  return type() == StringNodeType;
129  }
130  bool isGroupNode() const
131  {
132  return type() == GroupNodeType;
133  }
134  bool isTryNode() const
135  {
136  return type() == TryNodeType;
137  }
138  bool isLabelNode() const
139  {
140  return type() == LabelNodeType;
141  }
142  virtual bool scanForDeclarations() const
143  {
144  return true;
145  }
146  virtual bool isIterationStatement() const
147  {
148  return false;
149  }
150 
151  virtual void breakCycle() { }
152 
153  // Processes all function and variable declarations below this node,
154  // adding them to symbol table or the current object depending on the
155  // execution context..
156  void processDecls(ExecState *);
157 
158  /*
159  Implementations of this method should call visitor->visit on all the
160  children nodes, and if they return value is non-0, update the link to the child.
161  The recurseVisitLink helper takes care of this
162  */
163  virtual void recurseVisit(NodeVisitor * /*visitor*/) {}
164 
165  template<typename T>
166  static void recurseVisitLink(NodeVisitor *visitor, RefPtr<T> &link)
167  {
168  if (!link) {
169  return;
170  }
171 
172  T *newLink = static_cast<T *>(visitor->visit(link.get()));
173  if (newLink) {
174  link = newLink;
175  }
176  }
177 
178  template<typename T>
179  static void recurseVisitLink(NodeVisitor *visitor, ListRefPtr<T> &link)
180  {
181  if (!link) {
182  return;
183  }
184 
185  T *newLink = static_cast<T *>(visitor->visit(link.get()));
186  if (newLink) {
187  link = newLink;
188  }
189  }
190 
191  JSValue *throwError(ExecState *, ErrorType, const UString &msg);
192  JSValue *throwError(ExecState *, ErrorType, const UString &msg, const Identifier &);
193  JSValue *throwUndefinedVariableError(ExecState *, const Identifier &);
194 
195  virtual OpValue generateEvalCode(CompileState *comp);
196 protected:
197  mutable int m_line;
198 private:
199  virtual void processVarDecl(ExecState *state);
200  virtual void processFuncDecl(ExecState *state);
201  friend class VarDeclVisitor;
202  friend class FuncDeclVisitor;
203 
204  // disallow assignment
205  Node &operator=(const Node &);
206  Node(const Node &other);
207 };
208 
209 class LocationNode : public Node
210 {
211 public:
212  bool isLocation() const override
213  {
214  return true;
215  }
216 
217  // For assignments, we need to conceptually evaluate the LHS to a reference before looking at the RHS
218  // generateRefBind corresponds to that action. It never issues an error. The returned
219  // reference should be passed to generateRefWrite when needed
220  virtual CompileReference *generateRefBind(CompileState *) = 0;
221 
222  // When we are doing a read-modify-write style op, or just plain read, we want to do a read
223  // right after the binding. This does that, and returns a reference for use of follow up
224  // writes.
225  virtual CompileReference *generateRefRead(CompileState *, OpValue *out) = 0;
226 
227  // Writes to a bound reference.
228  virtual void generateRefWrite(CompileState *,
229  CompileReference *ref, OpValue &valToStore) = 0;
230 
231  // The location nodes also handle deletes themselves. Note that this is called
232  // w/o generateRefBegin
233  virtual OpValue generateRefDelete(CompileState *) = 0;
234 
235  // For function calls, we also do a specialized lookup, getting both the value and the
236  // scope/this, also making sure it's not an activation.
237  virtual void generateRefFunc(CompileState *comp, OpValue *funOut, OpValue *thisOut) = 0;
238 };
239 
240 class StatementNode : public Node
241 {
242 public:
243  StatementNode();
244  void setLoc(int line0, int line1) const;
245  int firstLine() const
246  {
247  return lineNo();
248  }
249  int lastLine() const
250  {
251  return m_lastLine;
252  }
253  void hitStatement(ExecState *);
254 
255  void generateDebugInfoIfNeeded(CompileState *comp);
256 
257  virtual void generateExecCode(CompileState *);
258 private:
259  void generateDebugInfo(CompileState *comp);
260  mutable int m_lastLine;
261 };
262 
263 inline void StatementNode::generateDebugInfoIfNeeded(CompileState *comp)
264 {
265  if (comp->compileType() == Debug) {
266  generateDebugInfo(comp);
267  }
268 }
269 
270 class NullNode : public Node
271 {
272 public:
273  NullNode() {}
274  NodeType type() const override
275  {
276  return NullNodeType;
277  }
278  OpValue generateEvalCode(CompileState *comp) override;
279  void streamTo(SourceStream &) const override;
280 };
281 
282 class BooleanNode : public Node
283 {
284 public:
285  BooleanNode(bool v) : val(v) {}
286  bool value() const
287  {
288  return val;
289  }
290 
291  NodeType type() const override
292  {
293  return BooleanNodeType;
294  }
295  OpValue generateEvalCode(CompileState *comp) override;
296  void streamTo(SourceStream &) const override;
297 private:
298  bool val;
299 };
300 
301 class NumberNode : public Node
302 {
303 public:
304  NumberNode(double v) : val(v) {}
305  double value() const
306  {
307  return val;
308  }
309  void setValue(double v)
310  {
311  val = v;
312  }
313 
314  NodeType type() const override
315  {
316  return NumberNodeType;
317  }
318  OpValue generateEvalCode(CompileState *comp) override;
319  void streamTo(SourceStream &) const override;
320 private:
321  double val;
322 };
323 
324 class StringNode : public Node
325 {
326 public:
327  StringNode(const UString *v) : val(*v), interned(nullptr) { }
328  ~StringNode() override; // in nodes2bytecode.cpp
329  UString value() const
330  {
331  return val;
332  }
333  void setValue(const UString &v)
334  {
335  val = v;
336  }
337 
338  NodeType type() const override
339  {
340  return StringNodeType;
341  }
342  OpValue generateEvalCode(CompileState *comp) override;
343  void streamTo(SourceStream &) const override;
344 private:
345  UString val;
346  StringImp *interned;
347 };
348 
349 class RegExpNode : public Node
350 {
351 public:
352  RegExpNode(const UString &p, const UString &f)
353  : pattern(p), flags(f) { }
354  NodeType type() const override
355  {
356  return RegExpNodeType;
357  }
358  OpValue generateEvalCode(CompileState *comp) override;
359  void streamTo(SourceStream &) const override;
360 private:
361  UString pattern, flags;
362 };
363 
364 class ThisNode : public Node
365 {
366 public:
367  ThisNode() {}
368  OpValue generateEvalCode(CompileState *comp) override;
369  void streamTo(SourceStream &) const override;
370 };
371 
372 class VarAccessNode : public LocationNode
373 {
374 public:
375  VarAccessNode(const Identifier &s) : ident(s) {}
376 
377  bool isVarAccessNode() const override
378  {
379  return true;
380  }
381  void streamTo(SourceStream &) const override;
382  OpValue generateEvalCode(CompileState *comp) override;
383 
384  CompileReference *generateRefBind(CompileState *) override;
385  CompileReference *generateRefRead(CompileState *, OpValue *out) override;
386  void generateRefWrite(CompileState *,
387  CompileReference *ref, OpValue &valToStore) override;
388  OpValue generateRefDelete(CompileState *) override;
389  void generateRefFunc(CompileState *comp, OpValue *funOut, OpValue *thisOut) override;
390 
391  // This one never fails..
392  OpValue valueForTypeOf(CompileState *comp);
393 
394  // Returns the ID this variable should be accessed as, or
395  // missingSymbolMarker(), along with the variable's classification
396  enum Classification {
397  Local, // local variable accessed by register #
398  NonLocal, // one scope above, unless local injected
399  Dynamic, // need to do a full lookup
400  Global // in the global object, if anywhere.
401  };
402 
403  size_t classifyVariable(CompileState *, Classification &classify);
404 protected:
405  Identifier ident;
406 };
407 
408 class GroupNode : public Node
409 {
410 public:
411  GroupNode(Node *g) : group(g) { }
412  NodeType type() const override
413  {
414  return GroupNodeType;
415  }
416 
417  OpValue generateEvalCode(CompileState *comp) override;
418  Node *nodeInsideAllParens() override;
419  void streamTo(SourceStream &) const override;
420  void recurseVisit(NodeVisitor *visitor) override;
421 private:
422  RefPtr<Node> group;
423 };
424 
425 class ElementNode : public Node
426 {
427 public:
428  // list pointer is tail of a circular list, cracked in the ArrayNode ctor
429  ElementNode(int e, Node *n) : next(this), elision(e), node(n)
430  {
431  Parser::noteNodeCycle(this);
432  }
433  ElementNode(ElementNode *l, int e, Node *n)
434  : next(l->next), elision(e), node(n)
435  {
436  l->next = this;
437  }
438 
439  void streamTo(SourceStream &) const override;
440  PassRefPtr<ElementNode> releaseNext()
441  {
442  return next.release();
443  }
444  void breakCycle() override;
445  void recurseVisit(NodeVisitor *visitor) override;
446 private:
447  friend class ArrayNode;
448  ListRefPtr<ElementNode> next;
449  int elision;
450  RefPtr<Node> node;
451 };
452 
453 class ArrayNode : public Node
454 {
455 public:
456  ArrayNode(int e) : elision(e), opt(true) { }
457  ArrayNode(ElementNode *ele)
458  : element(ele->next.release()), elision(0), opt(false)
459  {
460  Parser::removeNodeCycle(element.get());
461  }
462  ArrayNode(int eli, ElementNode *ele)
463  : element(ele->next.release()), elision(eli), opt(true)
464  {
465  Parser::removeNodeCycle(element.get());
466  }
467  OpValue generateEvalCode(CompileState *comp) override;
468  void streamTo(SourceStream &) const override;
469  void recurseVisit(NodeVisitor *visitor) override;
470  bool scanForDeclarations() const override
471  {
472  return false;
473  }
474 private:
475  RefPtr<ElementNode> element;
476  int elision;
477  bool opt;
478 };
479 
480 class PropertyNameNode : public Node
481 {
482 public:
483  PropertyNameNode(const Identifier &s) : str(s) { }
484  void streamTo(SourceStream &) const override;
485 private:
486  friend class ObjectLiteralNode;
487  Identifier str;
488 };
489 
490 class PropertyNode : public Node
491 {
492 public:
493  enum Type { Constant, Getter, Setter };
494  PropertyNode(PropertyNameNode *n, Node *a, Type t)
495  : name(n), assign(a), type(t) { }
496  void streamTo(SourceStream &) const override;
497  friend class PropertyListNode;
498  void recurseVisit(NodeVisitor *visitor) override;
499 private:
500  friend class ObjectLiteralNode;
501  RefPtr<PropertyNameNode> name;
502  RefPtr<Node> assign;
503  Type type;
504 };
505 
506 class PropertyListNode : public Node
507 {
508 public:
509  // list pointer is tail of a circular list, cracked in the ObjectLiteralNode ctor
510  PropertyListNode(PropertyNode *n)
511  : node(n), next(this)
512  {
513  Parser::noteNodeCycle(this);
514  }
515  PropertyListNode(PropertyNode *n, PropertyListNode *l)
516  : node(n), next(l->next)
517  {
518  l->next = this;
519  }
520  void streamTo(SourceStream &) const override;
521  PassRefPtr<PropertyListNode> releaseNext()
522  {
523  return next.release();
524  }
525  void breakCycle() override;
526  void recurseVisit(NodeVisitor *visitor) override;
527 private:
528  friend class ObjectLiteralNode;
529  RefPtr<PropertyNode> node;
530  ListRefPtr<PropertyListNode> next;
531 };
532 
533 class ObjectLiteralNode : public Node
534 {
535 public:
536  ObjectLiteralNode() { }
537  ObjectLiteralNode(PropertyListNode *l) : list(l->next.release())
538  {
539  Parser::removeNodeCycle(list.get());
540  }
541  OpValue generateEvalCode(CompileState *comp) override;
542  void streamTo(SourceStream &) const override;
543  void recurseVisit(NodeVisitor *visitor) override;
544  bool scanForDeclarations() const override
545  {
546  return false;
547  }
548 private:
549  RefPtr<PropertyListNode> list;
550 };
551 
552 class BracketAccessorNode : public LocationNode
553 {
554 public:
555  BracketAccessorNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
556  void streamTo(SourceStream &) const override;
557 
558  OpValue generateEvalCode(CompileState *comp) override;
559 
560  CompileReference *generateRefBind(CompileState *) override;
561  CompileReference *generateRefRead(CompileState *, OpValue *out) override;
562  void generateRefWrite(CompileState *,
563  CompileReference *ref, OpValue &valToStore) override;
564  OpValue generateRefDelete(CompileState *) override;
565  void generateRefFunc(CompileState *comp, OpValue *funOut, OpValue *thisOut) override;
566 
567  Node *base()
568  {
569  return expr1.get();
570  }
571  Node *subscript()
572  {
573  return expr2.get();
574  }
575 
576  void recurseVisit(NodeVisitor *visitor) override;
577 protected:
578  RefPtr<Node> expr1;
579  RefPtr<Node> expr2;
580 };
581 
582 class DotAccessorNode : public LocationNode
583 {
584 public:
585  DotAccessorNode(Node *e, const Identifier &s) : expr(e), ident(s) { }
586  void streamTo(SourceStream &) const override;
587 
588  OpValue generateEvalCode(CompileState *comp) override;
589 
590  CompileReference *generateRefBind(CompileState *) override;
591  CompileReference *generateRefRead(CompileState *, OpValue *out) override;
592  void generateRefWrite(CompileState *,
593  CompileReference *ref, OpValue &valToStore) override;
594  OpValue generateRefDelete(CompileState *) override;
595  void generateRefFunc(CompileState *comp, OpValue *funOut, OpValue *thisOut) override;
596 
597  Node *base() const
598  {
599  return expr.get();
600  }
601  const Identifier &identifier() const
602  {
603  return ident;
604  }
605 
606  void recurseVisit(NodeVisitor *visitor) override;
607 protected:
608  RefPtr<Node> expr;
609  Identifier ident;
610 };
611 
612 class ArgumentListNode : public Node
613 {
614 public:
615  // list pointer is tail of a circular list, cracked in the ArgumentsNode ctor
616  ArgumentListNode(Node *e) : next(this), expr(e)
617  {
618  Parser::noteNodeCycle(this);
619  }
620  ArgumentListNode(ArgumentListNode *l, Node *e)
621  : next(l->next), expr(e)
622  {
623  l->next = this;
624  }
625 
626  void streamTo(SourceStream &) const override;
627  PassRefPtr<ArgumentListNode> releaseNext()
628  {
629  return next.release();
630  }
631  void breakCycle() override;
632 
633  void recurseVisit(NodeVisitor *visitor) override;
634 private:
635  friend class ArgumentsNode;
636  ListRefPtr<ArgumentListNode> next;
637  RefPtr<Node> expr;
638 };
639 
640 class ArgumentsNode : public Node
641 {
642 public:
643  ArgumentsNode() { }
644  ArgumentsNode(ArgumentListNode *l)
645  : list(l->next.release())
646  {
647  Parser::removeNodeCycle(list.get());
648  }
649 
650  void generateEvalArguments(CompileState *comp);
651  void streamTo(SourceStream &) const override;
652 
653  void recurseVisit(NodeVisitor *visitor) override;
654 private:
655  RefPtr<ArgumentListNode> list;
656 };
657 
658 class NewExprNode : public Node
659 {
660 public:
661  NewExprNode(Node *e) : expr(e) {}
662  NewExprNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
663 
664  OpValue generateEvalCode(CompileState *comp) override;
665  void streamTo(SourceStream &) const override;
666  void recurseVisit(NodeVisitor *visitor) override;
667 private:
668  RefPtr<Node> expr;
669  RefPtr<ArgumentsNode> args;
670 };
671 
672 class FunctionCallValueNode : public Node
673 {
674 public:
675  FunctionCallValueNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
676 
677  OpValue generateEvalCode(CompileState *comp) override;
678  void streamTo(SourceStream &) const override;
679  void recurseVisit(NodeVisitor *visitor) override;
680 private:
681  RefPtr<Node> expr;
682  RefPtr<ArgumentsNode> args;
683 };
684 
685 class FunctionCallReferenceNode : public Node
686 {
687 public:
688  FunctionCallReferenceNode(Node *e, ArgumentsNode *a) : expr(e), args(a) {}
689 
690  OpValue generateEvalCode(CompileState *comp) override;
691  void streamTo(SourceStream &) const override;
692  void recurseVisit(NodeVisitor *visitor) override;
693 private:
694  RefPtr<Node> expr;
695  RefPtr<ArgumentsNode> args;
696 };
697 
698 class PostfixNode : public Node
699 {
700 public:
701  PostfixNode(Node *l, Operator o) : m_loc(l), m_oper(o) {}
702 
703  void streamTo(SourceStream &) const override;
704  void recurseVisit(NodeVisitor *visitor) override;
705  OpValue generateEvalCode(CompileState *comp) override;
706 protected:
707  RefPtr<Node> m_loc;
708  Operator m_oper;
709 };
710 
711 class DeleteReferenceNode : public Node
712 {
713 public:
714  DeleteReferenceNode(LocationNode *l) : loc(l) {}
715 
716  void streamTo(SourceStream &) const override;
717  void recurseVisit(NodeVisitor *visitor) override;
718  OpValue generateEvalCode(CompileState *comp) override;
719 private:
720  RefPtr<LocationNode> loc;
721 };
722 
723 class DeleteValueNode : public Node
724 {
725 public:
726  DeleteValueNode(Node *e) : m_expr(e) {}
727 
728  void streamTo(SourceStream &) const override;
729  void recurseVisit(NodeVisitor *visitor) override;
730  OpValue generateEvalCode(CompileState *comp) override;
731 private:
732  RefPtr<Node> m_expr;
733 };
734 
735 class VoidNode : public Node
736 {
737 public:
738  VoidNode(Node *e) : expr(e) {}
739 
740  OpValue generateEvalCode(CompileState *comp) override;
741  void streamTo(SourceStream &) const override;
742  void recurseVisit(NodeVisitor *visitor) override;
743 private:
744  RefPtr<Node> expr;
745 };
746 
747 class TypeOfVarNode : public Node
748 {
749 public:
750  TypeOfVarNode(VarAccessNode *l) : loc(l) {}
751 
752  OpValue generateEvalCode(CompileState *comp) override;
753  void streamTo(SourceStream &) const override;
754  void recurseVisit(NodeVisitor *visitor) override;
755 private:
756  RefPtr<VarAccessNode> loc;
757 };
758 
759 class TypeOfValueNode : public Node
760 {
761 public:
762  TypeOfValueNode(Node *e) : m_expr(e) {}
763 
764  OpValue generateEvalCode(CompileState *comp) override;
765  void streamTo(SourceStream &) const override;
766  void recurseVisit(NodeVisitor *visitor) override;
767 private:
768  RefPtr<Node> m_expr;
769 };
770 
771 class PrefixNode : public Node
772 {
773 public:
774  PrefixNode(Node *l, Operator o) : m_loc(l), m_oper(o) {}
775 
776  OpValue generateEvalCode(CompileState *comp) override;
777  void streamTo(SourceStream &) const override;
778  void recurseVisit(NodeVisitor *visitor) override;
779 protected:
780  RefPtr<Node> m_loc;
781  Operator m_oper;
782 };
783 
784 class UnaryPlusNode : public Node
785 {
786 public:
787  UnaryPlusNode(Node *e) : expr(e) {}
788 
789  OpValue generateEvalCode(CompileState *comp) override;
790  void streamTo(SourceStream &) const override;
791  void recurseVisit(NodeVisitor *visitor) override;
792 private:
793  RefPtr<Node> expr;
794 };
795 
796 class NegateNode : public Node
797 {
798 public:
799  NegateNode(Node *e) : expr(e) {}
800 
801  OpValue generateEvalCode(CompileState *comp) override;
802  void streamTo(SourceStream &) const override;
803  void recurseVisit(NodeVisitor *visitor) override;
804 private:
805  RefPtr<Node> expr;
806 };
807 
808 class BitwiseNotNode : public Node
809 {
810 public:
811  BitwiseNotNode(Node *e) : expr(e) {}
812 
813  OpValue generateEvalCode(CompileState *comp) override;
814  void streamTo(SourceStream &) const override;
815  void recurseVisit(NodeVisitor *visitor) override;
816 private:
817  RefPtr<Node> expr;
818 };
819 
820 class LogicalNotNode : public Node
821 {
822 public:
823  LogicalNotNode(Node *e) : expr(e) {}
824 
825  OpValue generateEvalCode(CompileState *comp) override;
826  void streamTo(SourceStream &) const override;
827  void recurseVisit(NodeVisitor *visitor) override;
828 private:
829  RefPtr<Node> expr;
830 };
831 
832 class BinaryOperatorNode : public Node
833 {
834 public:
835  BinaryOperatorNode(Node *e1, Node *e2, Operator op)
836  : expr1(e1), expr2(e2), oper(op) {}
837 
838  OpValue generateEvalCode(CompileState *comp) override;
839  void streamTo(SourceStream &) const override;
840  void recurseVisit(NodeVisitor *visitor) override;
841 private:
842  RefPtr<Node> expr1;
843  RefPtr<Node> expr2;
844  Operator oper;
845 };
846 
847 /**
848  * expr1 && expr2, expr1 || expr2
849  */
850 class BinaryLogicalNode : public Node
851 {
852 public:
853  BinaryLogicalNode(Node *e1, Operator o, Node *e2) :
854  expr1(e1), expr2(e2), oper(o) {}
855 
856  OpValue generateEvalCode(CompileState *comp) override;
857  void streamTo(SourceStream &) const override;
858  void recurseVisit(NodeVisitor *visitor) override;
859 private:
860  RefPtr<Node> expr1;
861  RefPtr<Node> expr2;
862  Operator oper;
863 };
864 
865 /**
866  * The ternary operator, "logical ? expr1 : expr2"
867  */
868 class ConditionalNode : public Node
869 {
870 public:
871  ConditionalNode(Node *l, Node *e1, Node *e2) :
872  logical(l), expr1(e1), expr2(e2) {}
873 
874  OpValue generateEvalCode(CompileState *comp) override;
875  void streamTo(SourceStream &) const override;
876  void recurseVisit(NodeVisitor *visitor) override;
877 private:
878  RefPtr<Node> logical;
879  RefPtr<Node> expr1;
880  RefPtr<Node> expr2;
881 };
882 
883 class AssignNode : public Node
884 {
885 public:
886  AssignNode(Node *loc, Operator oper, Node *right)
887  : m_loc(loc), m_oper(oper), m_right(right) {}
888 
889  void streamTo(SourceStream &) const override;
890  OpValue generateEvalCode(CompileState *comp) override;
891  void recurseVisit(NodeVisitor *visitor) override;
892 protected:
893  RefPtr<Node> m_loc;
894  Operator m_oper;
895  RefPtr<Node> m_right;
896 };
897 
898 class CommaNode : public Node
899 {
900 public:
901  CommaNode(Node *e1, Node *e2) : expr1(e1), expr2(e2) {}
902 
903  void streamTo(SourceStream &) const override;
904  void recurseVisit(NodeVisitor *visitor) override;
905  OpValue generateEvalCode(CompileState *comp) override;
906 private:
907  RefPtr<Node> expr1;
908  RefPtr<Node> expr2;
909 };
910 
911 class AssignExprNode : public Node
912 {
913 public:
914  AssignExprNode(Node *e) : expr(e) {}
915 
916  void streamTo(SourceStream &) const override;
917  void recurseVisit(NodeVisitor *visitor) override;
918  OpValue generateEvalCode(CompileState *comp) override;
919 
920  Node *getExpr()
921  {
922  return expr.get();
923  }
924 private:
925  RefPtr<Node> expr;
926 };
927 
928 class VarDeclNode : public Node
929 {
930 public:
931  enum Type { Variable, Constant };
932  VarDeclNode(const Identifier &id, AssignExprNode *in, Type t);
933 
934  void generateCode(CompileState *comp);
935 
936  void streamTo(SourceStream &) const override;
937  void recurseVisit(NodeVisitor *visitor) override;
938 
939  void processVarDecl(ExecState *) override;
940 private:
941  friend class VarStatementNode;
942  friend class VarDeclListNode;
943  Type varType;
944  Identifier ident;
945  RefPtr<AssignExprNode> init;
946 };
947 
948 class VarDeclListNode : public Node
949 {
950 public:
951  // list pointer is tail of a circular list, cracked in the ForNode/VarStatementNode ctor
952  VarDeclListNode(VarDeclNode *v) : next(this), var(v)
953  {
954  Parser::noteNodeCycle(this);
955  }
956  VarDeclListNode(VarDeclListNode *l, VarDeclNode *v)
957  : next(l->next), var(v)
958  {
959  l->next = this;
960  }
961 
962  OpValue generateEvalCode(CompileState *comp) override;
963  void streamTo(SourceStream &) const override;
964  PassRefPtr<VarDeclListNode> releaseNext()
965  {
966  return next.release();
967  }
968  void breakCycle() override;
969  void recurseVisit(NodeVisitor *visitor) override;
970 private:
971  friend class ForNode;
972  friend class VarStatementNode;
973  ListRefPtr<VarDeclListNode> next;
974  RefPtr<VarDeclNode> var;
975 };
976 
977 class VarStatementNode : public StatementNode
978 {
979 public:
980  VarStatementNode(VarDeclListNode *l) : next(l->next.release())
981  {
982  Parser::removeNodeCycle(next.get());
983  }
984 
985  void streamTo(SourceStream &) const override;
986  void recurseVisit(NodeVisitor *visitor) override;
987  void generateExecCode(CompileState *) override;
988 private:
989  RefPtr<VarDeclListNode> next;
990 };
991 
992 class BlockNode : public StatementNode
993 {
994 public:
995  BlockNode(SourceElementsNode *s);
996 
997  void streamTo(SourceStream &) const override;
998  void recurseVisit(NodeVisitor *visitor) override;
999  void generateExecCode(CompileState *) override;
1000 protected:
1001  RefPtr<SourceElementsNode> source;
1002 };
1003 
1004 class EmptyStatementNode : public StatementNode
1005 {
1006 public:
1007  EmptyStatementNode() { } // debug
1008 
1009  void streamTo(SourceStream &) const override;
1010  void generateExecCode(CompileState *) override;
1011 };
1012 
1013 class ExprStatementNode : public StatementNode
1014 {
1015 public:
1016  ExprStatementNode(Node *e) : expr(e) { }
1017 
1018  void streamTo(SourceStream &) const override;
1019  void recurseVisit(NodeVisitor *visitor) override;
1020  void generateExecCode(CompileState *) override;
1021 private:
1022  RefPtr<Node> expr;
1023 };
1024 
1025 class IfNode : public StatementNode
1026 {
1027 public:
1028  IfNode(Node *e, StatementNode *s1, StatementNode *s2)
1029  : expr(e), statement1(s1), statement2(s2) {}
1030 
1031  void streamTo(SourceStream &) const override;
1032  void recurseVisit(NodeVisitor *visitor) override;
1033  void generateExecCode(CompileState *) override;
1034 private:
1035  RefPtr<Node> expr;
1036  RefPtr<StatementNode> statement1;
1037  RefPtr<StatementNode> statement2;
1038 };
1039 
1040 class DoWhileNode : public StatementNode
1041 {
1042 public:
1043  DoWhileNode(StatementNode *s, Node *e) : statement(s), expr(e) {}
1044 
1045  void streamTo(SourceStream &) const override;
1046  void recurseVisit(NodeVisitor *visitor) override;
1047  void generateExecCode(CompileState *) override;
1048  bool isIterationStatement() const override
1049  {
1050  return true;
1051  }
1052 private:
1053  RefPtr<StatementNode> statement;
1054  RefPtr<Node> expr;
1055 };
1056 
1057 class WhileNode : public StatementNode
1058 {
1059 public:
1060  WhileNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
1061 
1062  void streamTo(SourceStream &) const override;
1063  void recurseVisit(NodeVisitor *visitor) override;
1064  void generateExecCode(CompileState *) override;
1065  bool isIterationStatement() const override
1066  {
1067  return true;
1068  }
1069 private:
1070  RefPtr<Node> expr;
1071  RefPtr<StatementNode> statement;
1072 };
1073 
1074 class ForNode : public StatementNode
1075 {
1076 public:
1077  ForNode(Node *e1, Node *e2, Node *e3, StatementNode *s) :
1078  expr1(e1), expr2(e2), expr3(e3), statement(s) {}
1079  ForNode(VarDeclListNode *e1, Node *e2, Node *e3, StatementNode *s) :
1080  expr1(e1->next.release()), expr2(e2), expr3(e3), statement(s)
1081  {
1082  Parser::removeNodeCycle(expr1.get());
1083  }
1084 
1085  void generateExecCode(CompileState *) override;
1086  void streamTo(SourceStream &) const override;
1087  void recurseVisit(NodeVisitor *visitor) override;
1088  bool isIterationStatement() const override
1089  {
1090  return true;
1091  }
1092 private:
1093  RefPtr<Node> expr1;
1094  RefPtr<Node> expr2;
1095  RefPtr<Node> expr3;
1096  RefPtr<StatementNode> statement;
1097 };
1098 
1099 class ForInNode : public StatementNode
1100 {
1101 public:
1102  ForInNode(Node *l, Node *e, StatementNode *s);
1103  ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s);
1104 
1105  void generateExecCode(CompileState *) override;
1106  void streamTo(SourceStream &) const override;
1107  void recurseVisit(NodeVisitor *visitor) override;
1108  bool isIterationStatement() const override
1109  {
1110  return true;
1111  }
1112 private:
1113  Identifier ident;
1114  RefPtr<AssignExprNode> init;
1115  RefPtr<Node> lexpr;
1116  RefPtr<Node> expr;
1117  RefPtr<VarDeclNode> varDecl;
1118  RefPtr<StatementNode> statement;
1119 };
1120 
1121 class ContinueNode : public StatementNode
1122 {
1123 public:
1124  ContinueNode() : target(nullptr) { }
1125  ContinueNode(const Identifier &i) : ident(i), target(nullptr) { }
1126 
1127  void generateExecCode(CompileState *) override;
1128  void streamTo(SourceStream &) const override;
1129 private:
1130  Identifier ident;
1131  const Node *target;
1132 };
1133 
1134 class BreakNode : public StatementNode
1135 {
1136 public:
1137  BreakNode() : target(nullptr) { }
1138  BreakNode(const Identifier &i) : ident(i), target(nullptr) { }
1139 
1140  void generateExecCode(CompileState *) override;
1141  void streamTo(SourceStream &) const override;
1142 private:
1143  Identifier ident;
1144  const Node *target;
1145 };
1146 
1147 class ReturnNode : public StatementNode
1148 {
1149 public:
1150  ReturnNode(Node *v) : value(v) {}
1151 
1152  void generateExecCode(CompileState *) override;
1153  void streamTo(SourceStream &) const override;
1154  void recurseVisit(NodeVisitor *visitor) override;
1155 private:
1156  RefPtr<Node> value;
1157 };
1158 
1159 class WithNode : public StatementNode
1160 {
1161 public:
1162  WithNode(Node *e, StatementNode *s) : expr(e), statement(s) {}
1163 
1164  void generateExecCode(CompileState *) override;
1165  void streamTo(SourceStream &) const override;
1166  void recurseVisit(NodeVisitor *visitor) override;
1167 private:
1168  RefPtr<Node> expr;
1169  RefPtr<StatementNode> statement;
1170 };
1171 
1172 class LabelNode : public StatementNode
1173 {
1174 public:
1175  LabelNode(const Identifier &l, StatementNode *s) : label(l), statement(s) { }
1176 
1177  void streamTo(SourceStream &) const override;
1178  void recurseVisit(NodeVisitor *visitor) override;
1179  void generateExecCode(CompileState *) override;
1180  NodeType type() const override
1181  {
1182  return LabelNodeType;
1183  }
1184 private:
1185  Identifier label;
1186  RefPtr<StatementNode> statement;
1187 };
1188 
1189 class ThrowNode : public StatementNode
1190 {
1191 public:
1192  ThrowNode(Node *e) : expr(e) {}
1193 
1194  void generateExecCode(CompileState *) override;
1195  void streamTo(SourceStream &) const override;
1196  void recurseVisit(NodeVisitor *visitor) override;
1197 private:
1198  RefPtr<Node> expr;
1199 };
1200 
1201 class TryNode : public StatementNode
1202 {
1203 public:
1204  TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f)
1205  : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { }
1206  NodeType type() const override
1207  {
1208  return TryNodeType;
1209  }
1210 
1211  void generateExecCode(CompileState *) override;
1212  void streamTo(SourceStream &) const override;
1213  void recurseVisit(NodeVisitor *visitor) override;
1214 private:
1215  RefPtr<StatementNode> tryBlock;
1216  Identifier exceptionIdent;
1217  RefPtr<StatementNode> catchBlock;
1218  RefPtr<StatementNode> finallyBlock;
1219 };
1220 
1221 class ParameterNode : public Node
1222 {
1223 public:
1224  // list pointer is tail of a circular list, cracked in the FuncDeclNode/FuncExprNode ctor
1225  ParameterNode(const Identifier &i) : id(i), next(this)
1226  {
1227  Parser::noteNodeCycle(this);
1228  }
1229  ParameterNode(ParameterNode *next, const Identifier &i)
1230  : id(i), next(next->next)
1231  {
1232  next->next = this;
1233  }
1234 
1235  const Identifier &ident() const
1236  {
1237  return id;
1238  }
1239  ParameterNode *nextParam() const
1240  {
1241  return next.get();
1242  }
1243  void streamTo(SourceStream &) const override;
1244  PassRefPtr<ParameterNode> releaseNext()
1245  {
1246  return next.release();
1247  }
1248  void breakCycle() override;
1249 
1250  void recurseVisit(NodeVisitor *visitor) override;
1251 private:
1252  friend class FuncDeclNode;
1253  friend class FuncExprNode;
1254  Identifier id;
1255  ListRefPtr<ParameterNode> next;
1256 };
1257 
1258 // Flags about function bodies we care about for codegen
1259 enum FunctionBodyFlags {
1260  // note: neither of the two below is set for things created via
1261  // top-level, eval, or function ctor
1262  FuncFl_Decl = 1,
1263  FuncFl_Expr = 2,
1264  FuncFl_HasEvalOp = 4
1265 };
1266 
1267 /**
1268  This AST node corresponds to the function body or top-level code in the AST, but is used to
1269  keep track of much of the information relevant to the whole function,
1270  such as parameter names and symbol tables. This is because there are both function
1271  declarations and expressions, so there is no natural single place to put this stuff
1272  above the body
1273 
1274  inherited by ProgramNode
1275 */
1276 class FunctionBodyNode : public BlockNode
1277 {
1278 public:
1279  struct SymbolInfo {
1280  SymbolInfo(int _attr, FuncDeclNode *_funcDecl) : funcDecl(_funcDecl), attr(_attr) {}
1281  SymbolInfo() {}
1282  FuncDeclNode *funcDecl;
1283  int attr;
1284  };
1285  FunctionBodyNode(SourceElementsNode *);
1286  int sourceId()
1287  {
1288  return m_sourceId;
1289  }
1290  const UString &sourceURL()
1291  {
1292  return m_sourceURL;
1293  }
1294 
1295  bool isCompiled() const
1296  {
1297  return m_compType != NotCompiled;
1298  }
1299  void compileIfNeeded(CodeType ctype, CompileType compType);
1300  void compile(CodeType ctype, CompileType compType);
1301  CompileType compileState() const
1302  {
1303  return m_compType;
1304  }
1305 
1306  void generateExecCode(CompileState *) override;
1307 
1308  // Reserves a register for private use, making sure that id is in the right spot..
1309  void reserveSlot(size_t id, bool shouldMark);
1310 
1311  // Symbol table functions
1312  SymbolTable &symbolTable()
1313  {
1314  return m_symbolTable;
1315  }
1316  size_t lookupSymbolID(const Identifier &id) const
1317  {
1318  return m_symbolTable.get(id.ustring().rep());
1319  }
1320 
1321  int numLocalsAndRegisters() const
1322  {
1323  return m_symbolList.size();
1324  }
1325  SymbolInfo *getLocalInfo()
1326  {
1327  return m_symbolList.data();
1328  }
1329 
1330  size_t numFunctionLocals() const
1331  {
1332  return m_functionLocals.size();
1333  }
1334  size_t *getFunctionLocalInfo()
1335  {
1336  return m_functionLocals.data();
1337  }
1338 
1339  // Parameter stuff. We only collect the names during the parsing/
1340  // while FunctionImp is responsible for managing the IDs.
1341  void addParam(const Identifier &ident);
1342  size_t numParams() const
1343  {
1344  return m_paramList.size();
1345  }
1346  const Identifier &paramName(size_t pos) const
1347  {
1348  return m_paramList[pos];
1349  }
1350 
1351  void addVarDecl(const Identifier &ident, int attr, ExecState *exec);
1352  void addFunDecl(const Identifier &ident, int attr, FuncDeclNode *funcDecl);
1353 
1354  // Adds a new symbol, killing any previous ID.
1355  void addSymbolOverwriteID(size_t id, const Identifier &ident, int attr);
1356 
1357  // Runs the code, compiling if needed. This should only be used for non-function ExecStates
1358  Completion execute(ExecState *exec);
1359 
1360  bool tearOffAtEnd() const
1361  {
1362  return m_tearOffAtEnd;
1363  }
1364 
1365  const CodeBlock &code() const
1366  {
1367  return m_compiledCode;
1368  }
1369  CodeBlock &code()
1370  {
1371  return m_compiledCode;
1372  }
1373 
1374  // Collection of FuncFl_* flags describing information collected about this function
1375  // during the parsing.
1376  unsigned flags() const
1377  {
1378  return m_flags;
1379  }
1380 
1381 private:
1382  size_t addSymbol(const Identifier &ident, int attr, FuncDeclNode *funcDecl = nullptr);
1383  UString m_sourceURL;
1384  int m_sourceId : 31;
1385  bool m_tearOffAtEnd : 1;
1386  CompileType m_compType;
1387 
1388  // Flags
1389  unsigned m_flags;
1390 
1391  // This maps id -> attributes and function decl info
1392  WTF::Vector<SymbolInfo> m_symbolList;
1393 
1394  // This contains the list of locals which contains function declarations
1395  WTF::Vector<size_t> m_functionLocals;
1396 
1397  // This maps name -> id
1398  SymbolTable m_symbolTable;
1399 
1400  // The list of parameter names
1401  WTF::Vector<Identifier> m_paramList;
1402 
1403  CodeBlock m_compiledCode;
1404 };
1405 
1406 inline void FunctionBodyNode::compileIfNeeded(CodeType ctype, CompileType compType)
1407 {
1408  if (m_compType != compType) {
1409  compile(ctype, compType);
1410  }
1411 }
1412 
1413 class FuncExprNode : public Node
1414 {
1415 public:
1416  FuncExprNode(const Identifier &i, FunctionBodyNode *b, ParameterNode *p = nullptr)
1417  : ident(i), param(p ? p->next.release() : PassRefPtr<ParameterNode>(nullptr)), body(b)
1418  {
1419  if (p) {
1420  Parser::removeNodeCycle(param.get());
1421  } addParams();
1422  }
1423 
1424  OpValue generateEvalCode(CompileState *comp) override;
1425  void streamTo(SourceStream &) const override;
1426  void recurseVisit(NodeVisitor *visitor) override;
1427  bool scanForDeclarations() const override
1428  {
1429  return false;
1430  }
1431 private:
1432  void addParams();
1433  // Used for streamTo
1434  friend class PropertyNode;
1435  Identifier ident;
1436  RefPtr<ParameterNode> param;
1437  RefPtr<FunctionBodyNode> body;
1438 };
1439 
1440 class FuncDeclNode : public StatementNode
1441 {
1442 public:
1443  FuncDeclNode(const Identifier &i, FunctionBodyNode *b)
1444  : ident(i), body(b)
1445  {
1446  addParams();
1447  }
1448  FuncDeclNode(const Identifier &i, ParameterNode *p, FunctionBodyNode *b)
1449  : ident(i), param(p->next.release()), body(b)
1450  {
1451  Parser::removeNodeCycle(param.get());
1452  addParams();
1453  }
1454 
1455  void generateExecCode(CompileState *) override;
1456  void streamTo(SourceStream &) const override;
1457  void recurseVisit(NodeVisitor *visitor) override;
1458  bool scanForDeclarations() const override
1459  {
1460  return false;
1461  }
1462 
1463  void processFuncDecl(ExecState *) override;
1464  FunctionImp *makeFunctionObject(ExecState *);
1465 private:
1466  void addParams();
1467  Identifier ident;
1468  RefPtr<ParameterNode> param;
1469  RefPtr<FunctionBodyNode> body;
1470 };
1471 
1472 // A linked list of source element nodes
1473 class SourceElementsNode : public StatementNode
1474 {
1475 public:
1476  // list pointer is tail of a circular list, cracked in the BlockNode (or subclass) ctor
1477  SourceElementsNode(StatementNode *);
1478  SourceElementsNode(SourceElementsNode *s1, StatementNode *s2);
1479 
1480  void generateExecCode(CompileState *) override;
1481  void streamTo(SourceStream &) const override;
1482  PassRefPtr<SourceElementsNode> releaseNext()
1483  {
1484  return next.release();
1485  }
1486  void breakCycle() override;
1487  void recurseVisit(NodeVisitor *visitor) override;
1488 private:
1489  friend class BlockNode;
1490  friend class CaseClauseNode;
1491  RefPtr<StatementNode> node;
1492  ListRefPtr<SourceElementsNode> next;
1493 };
1494 
1495 class CaseClauseNode : public Node
1496 {
1497 public:
1498  CaseClauseNode(Node *e) : expr(e) { }
1499  CaseClauseNode(Node *e, SourceElementsNode *s)
1500  : expr(e), source(s->next.release())
1501  {
1502  Parser::removeNodeCycle(source.get());
1503  }
1504 
1505  void streamTo(SourceStream &) const override;
1506  void recurseVisit(NodeVisitor *visitor) override;
1507 private:
1508  friend class SwitchNode;
1509  RefPtr<Node> expr;
1510  RefPtr<SourceElementsNode> source;
1511 };
1512 
1513 class ClauseListNode : public Node
1514 {
1515 public:
1516  // list pointer is tail of a circular list, cracked in the CaseBlockNode ctor
1517  ClauseListNode(CaseClauseNode *c) : clause(c), next(this)
1518  {
1519  Parser::noteNodeCycle(this);
1520  }
1521  ClauseListNode(ClauseListNode *n, CaseClauseNode *c)
1522  : clause(c), next(n->next)
1523  {
1524  n->next = this;
1525  }
1526 
1527  CaseClauseNode *getClause() const
1528  {
1529  return clause.get();
1530  }
1531  ClauseListNode *getNext() const
1532  {
1533  return next.get();
1534  }
1535  void streamTo(SourceStream &) const override;
1536  PassRefPtr<ClauseListNode> releaseNext()
1537  {
1538  return next.release();
1539  }
1540  void breakCycle() override;
1541  void recurseVisit(NodeVisitor *visitor) override;
1542 private:
1543  friend class SwitchNode;
1544  friend class CaseBlockNode;
1545  RefPtr<CaseClauseNode> clause;
1546  ListRefPtr<ClauseListNode> next;
1547 };
1548 
1549 class CaseBlockNode : public Node
1550 {
1551 public:
1552  CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d, ClauseListNode *l2);
1553 
1554  void streamTo(SourceStream &) const override;
1555  void recurseVisit(NodeVisitor *visitor) override;
1556 private:
1557  friend class SwitchNode;
1558  RefPtr<ClauseListNode> list1;
1559  RefPtr<CaseClauseNode> def;
1560  RefPtr<ClauseListNode> list2;
1561 };
1562 
1563 class SwitchNode : public StatementNode
1564 {
1565 public:
1566  SwitchNode(Node *e, CaseBlockNode *b) : expr(e), block(b) { }
1567 
1568  void streamTo(SourceStream &) const override;
1569  void recurseVisit(NodeVisitor *visitor) override;
1570  void generateExecCode(CompileState *comp) override;
1571 private:
1572  RefPtr<Node> expr;
1573  RefPtr<CaseBlockNode> block;
1574 };
1575 
1576 // important: these are also built when compiling things via the Function constructor
1577 // (see FunctionObjectImp::construct() and Parser::parseFunctionBody, so the existence
1578 // of this class rather than the bare FunctionBodyNode does not care much information.
1579 class ProgramNode : public FunctionBodyNode
1580 {
1581 public:
1582  ProgramNode(SourceElementsNode *s);
1583  void streamTo(SourceStream &) const override;
1584 };
1585 
1586 class PackageNameNode : public Node
1587 {
1588 public:
1589  PackageNameNode(const Identifier &i) : names(nullptr), id(i) { }
1590  PackageNameNode(PackageNameNode *n,
1591  const Identifier &i) : names(n), id(i) { }
1592 
1593  void streamTo(SourceStream &) const override;
1594  void recurseVisit(NodeVisitor *visitor) override;
1595 
1596  Completion loadSymbol(ExecState *exec, bool wildcard);
1597  PackageObject *resolvePackage(ExecState *exec);
1598 
1599 private:
1600  PackageObject *resolvePackage(ExecState *exec,
1601  JSObject *baseObject, Package *basePackage);
1602  RefPtr<PackageNameNode> names;
1603  Identifier id;
1604 };
1605 
1606 class ImportStatement : public StatementNode
1607 {
1608 public:
1609  ImportStatement(PackageNameNode *n) : name(n), wld(false) {}
1610  void enableWildcard()
1611  {
1612  wld = true;
1613  }
1614  void setAlias(const Identifier &a)
1615  {
1616  al = a;
1617  }
1618 
1619  void generateExecCode(CompileState *) override;
1620  void streamTo(SourceStream &) const override;
1621  void recurseVisit(NodeVisitor *visitor) override;
1622 private:
1623  void processVarDecl(ExecState *state) override;
1624  RefPtr<PackageNameNode> name;
1625  Identifier al;
1626  bool wld;
1627 };
1628 
1629 } // namespace
1630 
1631 #endif
This AST node corresponds to the function body or top-level code in the AST, but is used to keep trac...
Definition: nodes.h:1276
QString pattern(Mode mode=Reading)
virtual void release(quint64 objid)
Type type(const QSqlDatabase &db)
QCA_EXPORT void init()
void ref()
void deref()
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
KIOCORE_EXPORT CopyJob * link(const QList< QUrl > &src, const QUrl &destDir, JobFlags flags=DefaultFlags)
Completion objects are used to convey the return status and value from functions.
Definition: completion.h:52
Represents the current state of script execution.
Definition: ExecState.h:53
char * toString(const T &value)
Represents an Identifier for a Javascript object.
Definition: identifier.h:36
expr1 && expr2, expr1 || expr2
Definition: nodes.h:850
QString label(StandardShortcut id)
QString name(StandardShortcut id)
The ternary operator, "logical ? expr1 : expr2".
Definition: nodes.h:868
const QList< QKeySequence > & next()
Unicode string class.
Definition: ustring.h:153
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sun Dec 4 2022 03:51:58 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.