2  *  Copyright (C) 2002 Harri Porten (porten@kde.org) 
   3  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 
   4  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org> 
   6  *  This library is free software; you can redistribute it and/or 
   7  *  modify it under the terms of the GNU Library General Public 
   8  *  License as published by the Free Software Foundation; either 
   9  *  version 2 of the License, or (at your option) any later version. 
  11  *  This library is distributed in the hope that it will be useful, 
  12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
  13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  14  *  Library General Public License for more details. 
  16  *  You should have received a copy of the GNU Library General Public License 
  17  *  along with this library; see the file COPYING.LIB.  If not, write to 
  18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
  19  *  Boston, MA 02110-1301, USA. 
  26 #include <wtf/MathExtras.h> 
  27 #include <wtf/StringExtras.h> 
  28 #include <wtf/unicode/Unicode.h> 
  31 using namespace Unicode
; 
  35 // A simple text streaming class that helps with code indentation. 
  37 enum EndlType 
{ Endl 
}; 
  38 enum IndentType 
{ Indent 
}; 
  39 enum UnindentType 
{ Unindent 
}; 
  40 enum DotExprType 
{ DotExpr 
}; 
  45         : m_numberNeedsParens(false) 
  46         , m_atStartOfStatement(true) 
  47         , m_precedence(PrecExpression
) 
  51     UString 
toString() const { return m_string
; } 
  53     SourceStream
& operator<<(const Identifier
&); 
  54     SourceStream
& operator<<(const UString
&); 
  55     SourceStream
& operator<<(const char*); 
  56     SourceStream
& operator<<(double); 
  57     SourceStream
& operator<<(char); 
  58     SourceStream
& operator<<(EndlType
); 
  59     SourceStream
& operator<<(IndentType
); 
  60     SourceStream
& operator<<(UnindentType
); 
  61     SourceStream
& operator<<(DotExprType
); 
  62     SourceStream
& operator<<(Precedence
); 
  63     SourceStream
& operator<<(const Node
*); 
  64     template <typename T
> SourceStream
& operator<<(const RefPtr
<T
>& n
) { return *this << n
.get(); } 
  68     UString m_spacesForIndentation
; 
  69     bool m_numberNeedsParens
; 
  70     bool m_atStartOfStatement
; 
  71     Precedence m_precedence
; 
  76 static UString 
escapeStringForPrettyPrinting(const UString
& s
) 
  78     UString escapedString
; 
  80     for (int i 
= 0; i 
< s
.size(); i
++) { 
  81         unsigned short c 
= s
.data()[i
].unicode(); 
  84                 escapedString 
+= "\\\""; 
  87                 escapedString 
+= "\\n"; 
  90                 escapedString 
+= "\\r"; 
  93                 escapedString 
+= "\\t"; 
  96                 escapedString 
+= "\\\\"; 
  99                 if (c 
< 128 && isPrintableChar(c
)) 
 100                     escapedString
.append(c
); 
 103                     snprintf(hexValue
, 7, "\\u%04x", c
); 
 104                     escapedString 
+= hexValue
; 
 109     return escapedString
; 
 112 static const char* operatorString(Operator oper
) 
 144     ASSERT_NOT_REACHED(); 
 148 static bool isParserRoundTripNumber(const UString
& string
) 
 150     double number 
= string
.toDouble(false, false); 
 151     if (isnan(number
) || isinf(number
)) 
 153     return string 
== UString::from(number
); 
 158 SourceStream
& SourceStream::operator<<(char c
) 
 160     m_numberNeedsParens 
= false; 
 161     m_atStartOfStatement 
= false; 
 167 SourceStream
& SourceStream::operator<<(const char* s
) 
 169     m_numberNeedsParens 
= false; 
 170     m_atStartOfStatement 
= false; 
 175 SourceStream
& SourceStream::operator<<(double value
) 
 177     bool needParens 
= m_numberNeedsParens
; 
 178     m_numberNeedsParens 
= false; 
 179     m_atStartOfStatement 
= false; 
 182         m_string
.append('('); 
 183     m_string 
+= UString::from(value
); 
 185         m_string
.append(')'); 
 190 SourceStream
& SourceStream::operator<<(const UString
& s
) 
 192     m_numberNeedsParens 
= false; 
 193     m_atStartOfStatement 
= false; 
 198 SourceStream
& SourceStream::operator<<(const Identifier
& s
) 
 200     m_numberNeedsParens 
= false; 
 201     m_atStartOfStatement 
= false; 
 202     m_string 
+= s
.ustring(); 
 206 SourceStream
& SourceStream::operator<<(const Node
* n
) 
 208     bool needParens 
= (m_precedence 
!= PrecExpression 
&& n
->precedence() > m_precedence
) || (m_atStartOfStatement 
&& n
->needsParensIfLeftmost()); 
 209     m_precedence 
= PrecExpression
; 
 213         m_numberNeedsParens 
= false; 
 214         m_string
.append('('); 
 218         m_string
.append(')'); 
 222 SourceStream
& SourceStream::operator<<(EndlType
) 
 224     m_numberNeedsParens 
= false; 
 225     m_atStartOfStatement 
= true; 
 226     m_string
.append('\n'); 
 227     m_string
.append(m_spacesForIndentation
); 
 231 SourceStream
& SourceStream::operator<<(IndentType
) 
 233     m_numberNeedsParens 
= false; 
 234     m_atStartOfStatement 
= false; 
 235     m_spacesForIndentation 
+= "  "; 
 239 SourceStream
& SourceStream::operator<<(UnindentType
) 
 241     m_numberNeedsParens 
= false; 
 242     m_atStartOfStatement 
= false; 
 243     m_spacesForIndentation 
= m_spacesForIndentation
.substr(0, m_spacesForIndentation
.size() - 2); 
 247 inline SourceStream
& SourceStream::operator<<(DotExprType
) 
 249     m_numberNeedsParens 
= true; 
 253 inline SourceStream
& SourceStream::operator<<(Precedence precedence
) 
 255     m_precedence 
= precedence
; 
 259 static void streamLeftAssociativeBinaryOperator(SourceStream
& s
, Precedence precedence
, 
 260     const char* operatorString
, const Node
* left
, const Node
* right
) 
 262     s 
<< precedence 
<< left
 
 263         << ' ' << operatorString 
<< ' ' 
 264         << static_cast<Precedence
>(precedence 
- 1) << right
; 
 267 template <typename T
> static inline void streamLeftAssociativeBinaryOperator(SourceStream
& s
, 
 268     Precedence p
, const char* o
, const RefPtr
<T
>& l
, const RefPtr
<T
>& r
) 
 270     streamLeftAssociativeBinaryOperator(s
, p
, o
, l
.get(), r
.get()); 
 273 static inline void bracketNodeStreamTo(SourceStream
& s
, const RefPtr
<ExpressionNode
>& base
, const RefPtr
<ExpressionNode
>& subscript
) 
 275     s 
<< PrecCall 
<< base
.get() << "[" << subscript
.get() << "]"; 
 278 static inline void dotNodeStreamTo(SourceStream
& s
, const RefPtr
<ExpressionNode
>& base
, const Identifier
& ident
) 
 280     s 
<< DotExpr 
<< PrecCall 
<< base
.get() << "." << ident
; 
 285 UString 
Node::toString() const 
 289     return stream
.toString(); 
 294 void NullNode::streamTo(SourceStream
& s
) const 
 299 void FalseNode::streamTo(SourceStream
& s
) const 
 304 void TrueNode::streamTo(SourceStream
& s
) const 
 309 void PlaceholderTrueNode::streamTo(SourceStream
&) const 
 313 void NumberNode::streamTo(SourceStream
& s
) const 
 318 void StringNode::streamTo(SourceStream
& s
) const 
 320     s 
<< '"' << escapeStringForPrettyPrinting(m_value
) << '"'; 
 323 void RegExpNode::streamTo(SourceStream
& s
) const 
 325     s 
<< '/' <<  m_regExp
->pattern() << '/' << m_regExp
->flags(); 
 328 void ThisNode::streamTo(SourceStream
& s
) const 
 333 void ResolveNode::streamTo(SourceStream
& s
) const 
 338 void ElementNode::streamTo(SourceStream
& s
) const 
 340     for (const ElementNode
* n 
= this; n
; n 
= n
->m_next
.get()) { 
 341         for (int i 
= 0; i 
< n
->m_elision
; i
++) 
 343         s 
<< PrecAssignment 
<< n
->m_node
; 
 349 void ArrayNode::streamTo(SourceStream
& s
) const 
 351     s 
<< '[' << m_element
; 
 352     for (int i 
= 0; i 
< m_elision
; i
++) 
 354     // Parser consumes one elision comma if there's array elements 
 355     // present in the expression. 
 356     if (m_optional 
&& m_element
) 
 361 void ObjectLiteralNode::streamTo(SourceStream
& s
) const 
 364         s 
<< "{ " << m_list 
<< " }"; 
 369 void PropertyListNode::streamTo(SourceStream
& s
) const 
 372     for (const PropertyListNode
* n 
= m_next
.get(); n
; n 
= n
->m_next
.get()) 
 373         s 
<< ", " << n
->m_node
; 
 376 void PropertyNode::streamTo(SourceStream
& s
) const 
 380             UString propertyName 
= name().ustring(); 
 381             if (isParserRoundTripNumber(propertyName
)) 
 384                 s 
<< '"' << escapeStringForPrettyPrinting(propertyName
) << '"'; 
 385             s 
<< ": " << PrecAssignment 
<< m_assign
; 
 390             const FuncExprNode
* func 
= static_cast<const FuncExprNode
*>(m_assign
.get()); 
 391             if (m_type 
== Getter
) 
 395             s 
<< escapeStringForPrettyPrinting(name().ustring()) 
 396                 << "(" << func
->m_parameter 
<< ')' << func
->m_body
; 
 402 void BracketAccessorNode::streamTo(SourceStream
& s
) const 
 404     bracketNodeStreamTo(s
, m_base
, m_subscript
); 
 407 void DotAccessorNode::streamTo(SourceStream
& s
) const 
 409     dotNodeStreamTo(s
, m_base
, m_ident
); 
 412 void ArgumentListNode::streamTo(SourceStream
& s
) const 
 414     s 
<< PrecAssignment 
<< m_expr
; 
 415     for (ArgumentListNode
* n 
= m_next
.get(); n
; n 
= n
->m_next
.get()) 
 416         s 
<< ", " << PrecAssignment 
<< n
->m_expr
; 
 419 void ArgumentsNode::streamTo(SourceStream
& s
) const 
 421     s 
<< '(' << m_listNode 
<< ')'; 
 424 void NewExprNode::streamTo(SourceStream
& s
) const 
 426     s 
<< "new " << PrecMember 
<< m_expr 
<< m_args
; 
 429 void FunctionCallValueNode::streamTo(SourceStream
& s
) const 
 431     s 
<< PrecCall 
<< m_expr 
<< m_args
; 
 434 void FunctionCallResolveNode::streamTo(SourceStream
& s
) const 
 436     s 
<< m_ident 
<< m_args
; 
 439 void FunctionCallBracketNode::streamTo(SourceStream
& s
) const 
 441     bracketNodeStreamTo(s
, m_base
, m_subscript
); 
 445 void FunctionCallDotNode::streamTo(SourceStream
& s
) const 
 447     dotNodeStreamTo(s
, m_base
, m_ident
); 
 451 void PostIncResolveNode::streamTo(SourceStream
& s
) const 
 453     s 
<< m_ident 
<< "++"; 
 456 void PostDecResolveNode::streamTo(SourceStream
& s
) const 
 458     s 
<< m_ident 
<< "--"; 
 461 void PostIncBracketNode::streamTo(SourceStream
& s
) const 
 463     bracketNodeStreamTo(s
, m_base
, m_subscript
); 
 467 void PostDecBracketNode::streamTo(SourceStream
& s
) const 
 469     bracketNodeStreamTo(s
, m_base
, m_subscript
); 
 473 void PostIncDotNode::streamTo(SourceStream
& s
) const 
 475     dotNodeStreamTo(s
, m_base
, m_ident
); 
 479 void PostDecDotNode::streamTo(SourceStream
& s
) const 
 481     dotNodeStreamTo(s
, m_base
, m_ident
); 
 485 void PostfixErrorNode::streamTo(SourceStream
& s
) const 
 487     s 
<< PrecLeftHandSide 
<< m_expr
; 
 488     if (m_operator 
== OpPlusPlus
) 
 494 void DeleteResolveNode::streamTo(SourceStream
& s
) const 
 496     s 
<< "delete " << m_ident
; 
 499 void DeleteBracketNode::streamTo(SourceStream
& s
) const 
 502     bracketNodeStreamTo(s
, m_base
, m_subscript
); 
 505 void DeleteDotNode::streamTo(SourceStream
& s
) const 
 508     dotNodeStreamTo(s
, m_base
, m_ident
); 
 511 void DeleteValueNode::streamTo(SourceStream
& s
) const 
 513     s 
<< "delete " << PrecUnary 
<< m_expr
; 
 516 void VoidNode::streamTo(SourceStream
& s
) const 
 518     s 
<< "void " << PrecUnary 
<< m_expr
; 
 521 void TypeOfValueNode::streamTo(SourceStream
& s
) const 
 523     s 
<< "typeof " << PrecUnary 
<< m_expr
; 
 526 void TypeOfResolveNode::streamTo(SourceStream
& s
) const 
 528     s 
<< "typeof " << m_ident
; 
 531 void PreIncResolveNode::streamTo(SourceStream
& s
) const 
 533     s 
<< "++" << m_ident
; 
 536 void PreDecResolveNode::streamTo(SourceStream
& s
) const 
 538     s 
<< "--" << m_ident
; 
 541 void PreIncBracketNode::streamTo(SourceStream
& s
) const 
 544     bracketNodeStreamTo(s
, m_base
, m_subscript
); 
 547 void PreDecBracketNode::streamTo(SourceStream
& s
) const 
 550     bracketNodeStreamTo(s
, m_base
, m_subscript
); 
 553 void PreIncDotNode::streamTo(SourceStream
& s
) const 
 556     dotNodeStreamTo(s
, m_base
, m_ident
); 
 559 void PreDecDotNode::streamTo(SourceStream
& s
) const 
 562     dotNodeStreamTo(s
, m_base
, m_ident
); 
 565 void PrefixErrorNode::streamTo(SourceStream
& s
) const 
 567     if (m_operator 
== OpPlusPlus
) 
 568         s 
<< "++" << PrecUnary 
<< m_expr
; 
 570         s 
<< "--" << PrecUnary 
<< m_expr
; 
 573 void UnaryPlusNode::streamTo(SourceStream
& s
) const 
 575     s 
<< "+ " << PrecUnary 
<< m_expr
; 
 578 void NegateNode::streamTo(SourceStream
& s
) const 
 580     s 
<< "- " << PrecUnary 
<< m_expr
; 
 583 void BitwiseNotNode::streamTo(SourceStream
& s
) const 
 585     s 
<< "~" << PrecUnary 
<< m_expr
; 
 588 void LogicalNotNode::streamTo(SourceStream
& s
) const 
 590     s 
<< "!" << PrecUnary 
<< m_expr
; 
 593 void MultNode::streamTo(SourceStream
& s
) const 
 595     streamLeftAssociativeBinaryOperator(s
, precedence(), "*", m_term1
, m_term2
); 
 598 void DivNode::streamTo(SourceStream
& s
) const 
 600     streamLeftAssociativeBinaryOperator(s
, precedence(), "/", m_term1
, m_term2
); 
 603 void ModNode::streamTo(SourceStream
& s
) const 
 605     streamLeftAssociativeBinaryOperator(s
, precedence(), "%", m_term1
, m_term2
); 
 608 void AddNode::streamTo(SourceStream
& s
) const 
 610     streamLeftAssociativeBinaryOperator(s
, precedence(), "+", m_term1
, m_term2
); 
 613 void SubNode::streamTo(SourceStream
& s
) const 
 615     streamLeftAssociativeBinaryOperator(s
, precedence(), "-", m_term1
, m_term2
); 
 618 void LeftShiftNode::streamTo(SourceStream
& s
) const 
 620     streamLeftAssociativeBinaryOperator(s
, precedence(), "<<", m_term1
, m_term2
); 
 623 void RightShiftNode::streamTo(SourceStream
& s
) const 
 625     streamLeftAssociativeBinaryOperator(s
, precedence(), ">>", m_term1
, m_term2
); 
 628 void UnsignedRightShiftNode::streamTo(SourceStream
& s
) const 
 630     streamLeftAssociativeBinaryOperator(s
, precedence(), ">>>", m_term1
, m_term2
); 
 633 void LessNode::streamTo(SourceStream
& s
) const 
 635     streamLeftAssociativeBinaryOperator(s
, precedence(), "<", m_expr1
, m_expr2
); 
 638 void GreaterNode::streamTo(SourceStream
& s
) const 
 640     streamLeftAssociativeBinaryOperator(s
, precedence(), ">", m_expr1
, m_expr2
); 
 643 void LessEqNode::streamTo(SourceStream
& s
) const 
 645     streamLeftAssociativeBinaryOperator(s
, precedence(), "<=", m_expr1
, m_expr2
); 
 648 void GreaterEqNode::streamTo(SourceStream
& s
) const 
 650     streamLeftAssociativeBinaryOperator(s
, precedence(), ">=", m_expr1
, m_expr2
); 
 653 void InstanceOfNode::streamTo(SourceStream
& s
) const 
 655     streamLeftAssociativeBinaryOperator(s
, precedence(), "instanceof", m_expr1
, m_expr2
); 
 658 void InNode::streamTo(SourceStream
& s
) const 
 660     streamLeftAssociativeBinaryOperator(s
, precedence(), "in", m_expr1
, m_expr2
); 
 663 void EqualNode::streamTo(SourceStream
& s
) const 
 665     streamLeftAssociativeBinaryOperator(s
, precedence(), "==", m_expr1
, m_expr2
); 
 668 void NotEqualNode::streamTo(SourceStream
& s
) const 
 670     streamLeftAssociativeBinaryOperator(s
, precedence(), "!=", m_expr1
, m_expr2
); 
 673 void StrictEqualNode::streamTo(SourceStream
& s
) const 
 675     streamLeftAssociativeBinaryOperator(s
, precedence(), "===", m_expr1
, m_expr2
); 
 678 void NotStrictEqualNode::streamTo(SourceStream
& s
) const 
 680     streamLeftAssociativeBinaryOperator(s
, precedence(), "!==", m_expr1
, m_expr2
); 
 683 void BitAndNode::streamTo(SourceStream
& s
) const 
 685     streamLeftAssociativeBinaryOperator(s
, precedence(), "&", m_expr1
, m_expr2
); 
 688 void BitXOrNode::streamTo(SourceStream
& s
) const 
 690     streamLeftAssociativeBinaryOperator(s
, precedence(), "^", m_expr1
, m_expr2
); 
 693 void BitOrNode::streamTo(SourceStream
& s
) const 
 695     streamLeftAssociativeBinaryOperator(s
, precedence(), "|", m_expr1
, m_expr2
); 
 698 void LogicalAndNode::streamTo(SourceStream
& s
) const 
 700     streamLeftAssociativeBinaryOperator(s
, precedence(), "&&", m_expr1
, m_expr2
); 
 703 void LogicalOrNode::streamTo(SourceStream
& s
) const 
 705     streamLeftAssociativeBinaryOperator(s
, precedence(), "||", m_expr1
, m_expr2
); 
 708 void ConditionalNode::streamTo(SourceStream
& s
) const 
 710     s 
<< PrecLogicalOr 
<< m_logical
 
 711         << " ? " << PrecAssignment 
<< m_expr1
 
 712         << " : " << PrecAssignment 
<< m_expr2
; 
 715 void ReadModifyResolveNode::streamTo(SourceStream
& s
) const 
 717     s 
<< m_ident 
<< ' ' << operatorString(m_operator
) << ' ' << PrecAssignment 
<< m_right
; 
 720 void AssignResolveNode::streamTo(SourceStream
& s
) const 
 722     s 
<< m_ident 
<< " = " << PrecAssignment 
<< m_right
; 
 725 void ReadModifyBracketNode::streamTo(SourceStream
& s
) const 
 727     bracketNodeStreamTo(s
, m_base
, m_subscript
); 
 728     s 
<< ' ' << operatorString(m_operator
) << ' ' << PrecAssignment 
<< m_right
; 
 731 void AssignBracketNode::streamTo(SourceStream
& s
) const 
 733     bracketNodeStreamTo(s
, m_base
, m_subscript
); 
 734     s 
<< " = " << PrecAssignment 
<< m_right
; 
 737 void ReadModifyDotNode::streamTo(SourceStream
& s
) const 
 739     dotNodeStreamTo(s
, m_base
, m_ident
); 
 740     s 
<< ' ' << operatorString(m_operator
) << ' ' << PrecAssignment 
<< m_right
; 
 743 void AssignDotNode::streamTo(SourceStream
& s
) const 
 745     dotNodeStreamTo(s
, m_base
, m_ident
); 
 746     s 
<< " = " << PrecAssignment 
<< m_right
; 
 749 void AssignErrorNode::streamTo(SourceStream
& s
) const 
 751     s 
<< PrecLeftHandSide 
<< m_left 
<< ' ' 
 752         << operatorString(m_operator
) << ' ' << PrecAssignment 
<< m_right
; 
 755 void CommaNode::streamTo(SourceStream
& s
) const 
 757     s 
<< PrecAssignment 
<< m_expr1 
<< ", " << PrecAssignment 
<< m_expr2
; 
 760 void ConstDeclNode::streamTo(SourceStream
& s
) const 
 764         s 
<< " = " << m_init
; 
 765     for (ConstDeclNode
* n 
= m_next
.get(); n
; n 
= n
->m_next
.get()) { 
 766         s 
<< ", " << m_ident
; 
 768             s 
<< " = " << m_init
; 
 772 void ConstStatementNode::streamTo(SourceStream
& s
) const 
 774     s 
<< Endl 
<< "const " << m_next 
<< ';'; 
 777 static inline void statementListStreamTo(const Vector
<RefPtr
<StatementNode
> >& nodes
, SourceStream
& s
) 
 779     for (Vector
<RefPtr
<StatementNode
> >::const_iterator ptr 
= nodes
.begin(); ptr 
!= nodes
.end(); ptr
++) 
 783 void BlockNode::streamTo(SourceStream
& s
) const 
 785     s 
<< Endl 
<< "{" << Indent
; 
 786     statementListStreamTo(m_children
, s
); 
 787     s 
<< Unindent 
<< Endl 
<< "}"; 
 790 void ScopeNode::streamTo(SourceStream
& s
) const 
 792     s 
<< Endl 
<< "{" << Indent
; 
 794     bool printedVar 
= false; 
 795     for (size_t i 
= 0; i 
< m_varStack
.size(); ++i
) { 
 796         if (m_varStack
[i
].second 
== 0) { 
 802             s 
<< m_varStack
[i
].first
; 
 808     statementListStreamTo(m_children
, s
); 
 809     s 
<< Unindent 
<< Endl 
<< "}"; 
 812 void EmptyStatementNode::streamTo(SourceStream
& s
) const 
 817 void ExprStatementNode::streamTo(SourceStream
& s
) const 
 819     s 
<< Endl 
<< m_expr 
<< ';'; 
 822 void VarStatementNode::streamTo(SourceStream
& s
) const 
 824     s 
<< Endl 
<< "var " << m_expr 
<< ';'; 
 827 void IfNode::streamTo(SourceStream
& s
) const 
 829     s 
<< Endl 
<< "if (" << m_condition 
<< ')' << Indent 
<< m_ifBlock 
<< Unindent
; 
 832 void IfElseNode::streamTo(SourceStream
& s
) const 
 835     s 
<< Endl 
<< "else" << Indent 
<< m_elseBlock 
<< Unindent
; 
 838 void DoWhileNode::streamTo(SourceStream
& s
) const 
 840     s 
<< Endl 
<< "do " << Indent 
<< m_statement 
<< Unindent 
<< Endl
 
 841         << "while (" << m_expr 
<< ");"; 
 844 void WhileNode::streamTo(SourceStream
& s
) const 
 846     s 
<< Endl 
<< "while (" << m_expr 
<< ')' << Indent 
<< m_statement 
<< Unindent
; 
 849 void ForNode::streamTo(SourceStream
& s
) const 
 852         << (m_expr1WasVarDecl 
? "var " : "") 
 856         << ')' << Indent 
<< m_statement 
<< Unindent
; 
 859 void ForInNode::streamTo(SourceStream
& s
) const 
 861     s 
<< Endl 
<< "for ("; 
 862     if (m_identIsVarDecl
) { 
 867             s 
<< PrecLeftHandSide 
<< m_lexpr
; 
 869         s 
<< PrecLeftHandSide 
<< m_lexpr
; 
 871     s 
<< " in " << m_expr 
<< ')' << Indent 
<< m_statement 
<< Unindent
; 
 874 void ContinueNode::streamTo(SourceStream
& s
) const 
 876     s 
<< Endl 
<< "continue"; 
 877     if (!m_ident
.isNull()) 
 882 void BreakNode::streamTo(SourceStream
& s
) const 
 884     s 
<< Endl 
<< "break"; 
 885     if (!m_ident
.isNull()) 
 890 void ReturnNode::streamTo(SourceStream
& s
) const 
 892     s 
<< Endl 
<< "return"; 
 898 void WithNode::streamTo(SourceStream
& s
) const 
 900     s 
<< Endl 
<< "with (" << m_expr 
<< ") " << m_statement
; 
 903 void CaseClauseNode::streamTo(SourceStream
& s
) const 
 907         s 
<< "case " << m_expr
; 
 911     statementListStreamTo(m_children
, s
); 
 915 void ClauseListNode::streamTo(SourceStream
& s
) const 
 917     for (const ClauseListNode
* n 
= this; n
; n 
= n
->getNext()) 
 921 void CaseBlockNode::streamTo(SourceStream
& s
) const 
 923     for (const ClauseListNode
* n 
= m_list1
.get(); n
; n 
= n
->getNext()) 
 925     s 
<< m_defaultClause
; 
 926     for (const ClauseListNode
* n 
= m_list2
.get(); n
; n 
= n
->getNext()) 
 930 void SwitchNode::streamTo(SourceStream
& s
) const 
 932     s 
<< Endl 
<< "switch (" << m_expr 
<< ") {" 
 933         << Indent 
<< m_block 
<< Unindent
 
 937 void LabelNode::streamTo(SourceStream
& s
) const 
 939     s 
<< Endl 
<< m_label 
<< ":" << Indent 
<< m_statement 
<< Unindent
; 
 942 void ThrowNode::streamTo(SourceStream
& s
) const 
 944     s 
<< Endl 
<< "throw " << m_expr 
<< ';'; 
 947 void TryNode::streamTo(SourceStream
& s
) const 
 949     s 
<< Endl 
<< "try " << m_tryBlock
; 
 951         s 
<< Endl 
<< "catch (" << m_exceptionIdent 
<< ')' << m_catchBlock
; 
 953         s 
<< Endl 
<< "finally " << m_finallyBlock
; 
 956 void ParameterNode::streamTo(SourceStream
& s
) const 
 959     for (ParameterNode
* n 
= m_next
.get(); n
; n 
= n
->m_next
.get()) 
 960         s 
<< ", " << n
->m_ident
; 
 963 void FuncDeclNode::streamTo(SourceStream
& s
) const 
 965     s 
<< Endl 
<< "function " << m_ident 
<< '(' << m_parameter 
<< ')' << m_body
; 
 968 void FuncExprNode::streamTo(SourceStream
& s
) const 
 970     s 
<< "function " << m_ident 
<< '(' << m_parameter 
<< ')' << m_body
;