source: webkit/trunk/JavaScriptCore/kjs/nodes2string.cpp@ 28937

Last change on this file since 28937 was 28937, checked in by Darin Adler, 17 years ago

Reviewed by Eric.

1.022x as fast on SunSpider.

  • kjs/NodeInfo.h: Renamed SourceElementsStub to SourceElements, since that more accurately describes the role of this object, which is a reference-counted wrapper for a Vector.
  • kjs/Parser.cpp: (KJS::Parser::didFinishParsing): Changed parameter type to SourceElements, and use plain assignment instead of set.
  • kjs/Parser.h: Changed parameter type of didFinishParsing to a SourceElements. Also changed m_sourceElements; we now use a RefPtr instead of an OwnPtr as well.
  • kjs/grammar.y: Got rid of all the calls to release() on SourceElements. That's now handed inside the constructors for various node types, since we now use vector swapping instead.
  • kjs/nodes.cpp: (KJS::Node::rethrowException): Added NEVER_INLINE, because this was getting inlined and we want exception handling out of the normal code flow. (KJS::SourceElements::append): Moved here from the header. This now handles creating a BreakpointCheckStatement for each statement in the debugger case. That way we can get breakpoint handling without having it in every execute function. (KJS::BreakpointCheckStatement::BreakpointCheckStatement): Added. (KJS::BreakpointCheckStatement::execute): Added. Contains the code that was formerly in the StatementNode::hitStatement function and the KJS_BREAKPOINT macro. (KJS::BreakpointCheckStatement::streamTo): Added. (KJS::ArgumentListNode::evaluateList): Use KJS_CHECKEXCEPTIONVOID since the return type is void. (KJS::VarStatementNode::execute): Removed KJS_BREAKPOINT. (KJS::BlockNode::BlockNode): Changed parameter type to SourceElements. Changed code to use release since the class now contains a vector rather than a vector point. (KJS::BlockNode::optimizeVariableAccess): Updated since member is now a vector rather than a vector pointer. (KJS::BlockNode::execute): Ditto. (KJS::ExprStatementNode::execute): Removed KJS_BREAKPOINT. (KJS::IfNode::execute): Ditto. (KJS::IfElseNode::execute): Ditto. (KJS::DoWhileNode::execute): Ditto. (KJS::WhileNode::execute): Ditto. (KJS::ContinueNode::execute): Ditto. (KJS::BreakNode::execute): Ditto. (KJS::ReturnNode::execute): Ditto. (KJS::WithNode::execute): Ditto. (KJS::CaseClauseNode::optimizeVariableAccess): Updated since member is now a vector rather than a vector pointer. (KJS::CaseClauseNode::executeStatements): Ditto. (KJS::SwitchNode::execute): Removed KJS_BREAKPOINT. (KJS::ThrowNode::execute): Ditto. (KJS::TryNode::execute): Ditto. (KJS::ScopeNode::ScopeNode): Changed parameter type to SourceElements. (KJS::ProgramNode::ProgramNode): Ditto. (KJS::EvalNode::EvalNode): Ditto. (KJS::FunctionBodyNode::FunctionBodyNode): Ditto. (KJS::ScopeNode::optimizeVariableAccess): Updated since member is now a vector rather than a vector pointer.
  • kjs/nodes.h: Removed hitStatement. Renamed SourceElements to StatementVector. Renamed SourceElementsStub to SourceElements and made it derive from ParserRefCounted rather than from Node, hold a vector rather than a pointer to a vector, and changed the release function to swap with another vector rather than the pointer idiom. Updated BlockNode and CaseClauseNode to hold actual vectors instead of pointers to vectors. Added BreakpointCheckStatement.
  • kjs/nodes2string.cpp: (KJS::statementListStreamTo): Changed to work on a vector instead of a pointer to a vector. (KJS::BlockNode::streamTo): Ditto. (KJS::CaseClauseNode::streamTo): Ditto.
  • wtf/AlwaysInline.h: Added NEVER_INLINE.
  • wtf/PassRefPtr.h: Tweaked formatting. Added clear() function that matches the ones in OwnPtr and auto_ptr.
  • wtf/RefPtr.h: Ditto.
  • Property svn:eol-style set to native
File size: 21.1 KB
Line 
1/*
2 * Copyright (C) 2002 Harri Porten ([email protected])
3 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
4 * Copyright (C) 2007 Eric Seidel <[email protected]>
5 *
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.
10 *
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.
15 *
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.
20 *
21 */
22
23#include "config.h"
24#include "nodes.h"
25
26#include <wtf/MathExtras.h>
27#include <wtf/StringExtras.h>
28#include <wtf/unicode/Unicode.h>
29
30using namespace WTF;
31using namespace Unicode;
32
33namespace KJS {
34
35// A simple text streaming class that helps with code indentation.
36
37enum EndlType { Endl };
38enum IndentType { Indent };
39enum UnindentType { Unindent };
40enum DotExprType { DotExpr };
41
42class SourceStream {
43public:
44 SourceStream() : m_numberNeedsParens(false), m_precedence(PrecExpression) { }
45 UString toString() const { return m_string; }
46 SourceStream& operator<<(const Identifier&);
47 SourceStream& operator<<(const UString&);
48 SourceStream& operator<<(const char*);
49 SourceStream& operator<<(double);
50 SourceStream& operator<<(char);
51 SourceStream& operator<<(EndlType);
52 SourceStream& operator<<(IndentType);
53 SourceStream& operator<<(UnindentType);
54 SourceStream& operator<<(DotExprType);
55 SourceStream& operator<<(Precedence);
56 SourceStream& operator<<(const Node*);
57 template <typename T> SourceStream& operator<<(const RefPtr<T>& n) { return *this << n.get(); }
58
59private:
60 UString m_string;
61 UString m_spacesForIndentation;
62 bool m_numberNeedsParens;
63 Precedence m_precedence;
64};
65
66// --------
67
68static UString escapeStringForPrettyPrinting(const UString& s)
69{
70 UString escapedString;
71
72 for (int i = 0; i < s.size(); i++) {
73 unsigned short c = s.data()[i].unicode();
74 switch (c) {
75 case '\"':
76 escapedString += "\\\"";
77 break;
78 case '\n':
79 escapedString += "\\n";
80 break;
81 case '\r':
82 escapedString += "\\r";
83 break;
84 case '\t':
85 escapedString += "\\t";
86 break;
87 case '\\':
88 escapedString += "\\\\";
89 break;
90 default:
91 if (c < 128 && isPrintableChar(c))
92 escapedString.append(c);
93 else {
94 char hexValue[7];
95 snprintf(hexValue, 7, "\\u%04x", c);
96 escapedString += hexValue;
97 }
98 }
99 }
100
101 return escapedString;
102}
103
104static const char* operatorString(Operator oper)
105{
106 switch (oper) {
107 case OpEqual:
108 return "=";
109 case OpMultEq:
110 return "*=";
111 case OpDivEq:
112 return "/=";
113 case OpPlusEq:
114 return "+=";
115 case OpMinusEq:
116 return "-=";
117 case OpLShift:
118 return "<<=";
119 case OpRShift:
120 return ">>=";
121 case OpURShift:
122 return ">>>=";
123 case OpAndEq:
124 return "&=";
125 case OpXOrEq:
126 return "^=";
127 case OpOrEq:
128 return "|=";
129 case OpModEq:
130 return "%=";
131 case OpPlusPlus:
132 return "++";
133 case OpMinusMinus:
134 return "--";
135 }
136 ASSERT_NOT_REACHED();
137 return "???";
138}
139
140static bool isParserRoundTripNumber(const UString& string)
141{
142 double number = string.toDouble(false, false);
143 if (isnan(number) || isinf(number))
144 return false;
145 return string == UString::from(number);
146}
147
148// --------
149
150SourceStream& SourceStream::operator<<(char c)
151{
152 m_numberNeedsParens = false;
153 UChar ch(c);
154 m_string.append(ch);
155 return *this;
156}
157
158SourceStream& SourceStream::operator<<(const char* s)
159{
160 m_numberNeedsParens = false;
161 m_string += s;
162 return *this;
163}
164
165SourceStream& SourceStream::operator<<(double value)
166{
167 bool needParens = m_numberNeedsParens;
168 m_numberNeedsParens = false;
169
170 if (needParens)
171 m_string.append('(');
172 m_string += UString::from(value);
173 if (needParens)
174 m_string.append(')');
175
176 return *this;
177}
178
179SourceStream& SourceStream::operator<<(const UString& s)
180{
181 m_numberNeedsParens = false;
182 m_string += s;
183 return *this;
184}
185
186SourceStream& SourceStream::operator<<(const Identifier& s)
187{
188 m_numberNeedsParens = false;
189 m_string += s.ustring();
190 return *this;
191}
192
193SourceStream& SourceStream::operator<<(const Node* n)
194{
195 bool needParens = m_precedence != PrecExpression && n->precedence() > m_precedence;
196 m_precedence = PrecExpression;
197 if (n) {
198 if (needParens)
199 m_string.append('(');
200 n->streamTo(*this);
201 if (needParens)
202 m_string.append(')');
203 }
204 return *this;
205}
206
207SourceStream& SourceStream::operator<<(EndlType)
208{
209 m_numberNeedsParens = false;
210 m_string.append('\n');
211 m_string.append(m_spacesForIndentation);
212 return *this;
213}
214
215SourceStream& SourceStream::operator<<(IndentType)
216{
217 m_numberNeedsParens = false;
218 m_spacesForIndentation += " ";
219 return *this;
220}
221
222SourceStream& SourceStream::operator<<(UnindentType)
223{
224 m_numberNeedsParens = false;
225 m_spacesForIndentation = m_spacesForIndentation.substr(0, m_spacesForIndentation.size() - 2);
226 return *this;
227}
228
229inline SourceStream& SourceStream::operator<<(DotExprType)
230{
231 m_numberNeedsParens = true;
232 return *this;
233}
234
235inline SourceStream& SourceStream::operator<<(Precedence precedence)
236{
237 m_precedence = precedence;
238 return *this;
239}
240
241static void streamLeftAssociativeBinaryOperator(SourceStream& s, Precedence precedence,
242 const char* operatorString, const Node* left, const Node* right)
243{
244 s << precedence << left
245 << ' ' << operatorString << ' '
246 << static_cast<Precedence>(precedence - 1) << right;
247}
248
249template <typename T> static inline void streamLeftAssociativeBinaryOperator(SourceStream& s,
250 Precedence p, const char* o, const RefPtr<T>& l, const RefPtr<T>& r)
251{
252 streamLeftAssociativeBinaryOperator(s, p, o, l.get(), r.get());
253}
254
255// --------
256
257UString Node::toString() const
258{
259 SourceStream stream;
260 streamTo(stream);
261 return stream.toString();
262}
263
264// --------
265
266void NullNode::streamTo(SourceStream& s) const
267{
268 s << "null";
269}
270
271void FalseNode::streamTo(SourceStream& s) const
272{
273 s << "false";
274}
275
276void TrueNode::streamTo(SourceStream& s) const
277{
278 s << "true";
279}
280
281void NumberNode::streamTo(SourceStream& s) const
282{
283 s << value();
284}
285
286void StringNode::streamTo(SourceStream& s) const
287{
288 s << '"' << escapeStringForPrettyPrinting(m_value) << '"';
289}
290
291void RegExpNode::streamTo(SourceStream& s) const
292{
293 s << '/' << m_regExp->pattern() << '/' << m_regExp->flags();
294}
295
296void ThisNode::streamTo(SourceStream& s) const
297{
298 s << "this";
299}
300
301void ResolveNode::streamTo(SourceStream& s) const
302{
303 s << ident;
304}
305
306void ElementNode::streamTo(SourceStream& s) const
307{
308 for (const ElementNode* n = this; n; n = n->next.get()) {
309 for (int i = 0; i < n->elision; i++)
310 s << ',';
311 s << PrecAssignment << n->node;
312 if (n->next)
313 s << ',';
314 }
315}
316
317void ArrayNode::streamTo(SourceStream& s) const
318{
319 s << '[' << element;
320 for (int i = 0; i < elision; i++)
321 s << ',';
322 // Parser consumes one elision comma if there's array elements
323 // present in the expression.
324 if (opt && element)
325 s << ',';
326 s << ']';
327}
328
329void ObjectLiteralNode::streamTo(SourceStream& s) const
330{
331 if (list)
332 s << "{ " << list << " }";
333 else
334 s << "{ }";
335}
336
337void PropertyListNode::streamTo(SourceStream& s) const
338{
339 s << node;
340 for (const PropertyListNode* n = next.get(); n; n = n->next.get())
341 s << ", " << n->node;
342}
343
344void PropertyNode::streamTo(SourceStream& s) const
345{
346 switch (type) {
347 case Constant: {
348 UString propertyName = name().ustring();
349 if (isParserRoundTripNumber(propertyName))
350 s << propertyName;
351 else
352 s << '"' << escapeStringForPrettyPrinting(propertyName) << '"';
353 s << ": " << PrecAssignment << assign;
354 break;
355 }
356 case Getter:
357 case Setter: {
358 const FuncExprNode* func = static_cast<const FuncExprNode*>(assign.get());
359 if (type == Getter)
360 s << "get \"";
361 else
362 s << "set \"";
363 s << escapeStringForPrettyPrinting(name().ustring())
364 << "\"(" << func->param << ')' << func->body;
365 break;
366 }
367 }
368}
369
370void BracketAccessorNode::streamTo(SourceStream& s) const
371{
372 s << PrecCall << expr1 << "[" << expr2 << "]";
373}
374
375void DotAccessorNode::streamTo(SourceStream& s) const
376{
377 s << DotExpr << PrecCall << expr << "." << ident;
378}
379
380void ArgumentListNode::streamTo(SourceStream& s) const
381{
382 s << PrecAssignment << expr;
383 for (ArgumentListNode* n = next.get(); n; n = n->next.get())
384 s << ", " << PrecAssignment << n->expr;
385}
386
387void ArgumentsNode::streamTo(SourceStream& s) const
388{
389 s << '(' << listNode << ')';
390}
391
392void NewExprNode::streamTo(SourceStream& s) const
393{
394 s << "new " << PrecMember << expr << args;
395}
396
397void FunctionCallValueNode::streamTo(SourceStream& s) const
398{
399 s << PrecCall << expr << args;
400}
401
402void FunctionCallResolveNode::streamTo(SourceStream& s) const
403{
404 s << ident << args;
405}
406
407void FunctionCallBracketNode::streamTo(SourceStream& s) const
408{
409 s << PrecCall << base << "[" << subscript << "]" << args;
410}
411
412void FunctionCallDotNode::streamTo(SourceStream& s) const
413{
414 s << DotExpr << PrecCall << base << "." << ident << args;
415}
416
417void PostIncResolveNode::streamTo(SourceStream& s) const
418{
419 s << m_ident << "++";
420}
421
422void PostDecResolveNode::streamTo(SourceStream& s) const
423{
424 s << m_ident << "--";
425}
426
427void PostfixBracketNode::streamTo(SourceStream& s) const
428{
429 s << PrecCall << m_base << "[" << m_subscript << "]";
430 if (isIncrement())
431 s << "++";
432 else
433 s << "--";
434}
435
436void PostfixDotNode::streamTo(SourceStream& s) const
437{
438 s << DotExpr << PrecCall << m_base << "." << m_ident;
439 if (isIncrement())
440 s << "++";
441 else
442 s << "--";
443}
444
445void PostfixErrorNode::streamTo(SourceStream& s) const
446{
447 s << PrecLeftHandSide << m_expr;
448 if (m_oper == OpPlusPlus)
449 s << "++";
450 else
451 s << "--";
452}
453
454void DeleteResolveNode::streamTo(SourceStream& s) const
455{
456 s << "delete " << m_ident;
457}
458
459void DeleteBracketNode::streamTo(SourceStream& s) const
460{
461 s << "delete " << PrecCall << m_base << "[" << m_subscript << "]";
462}
463
464void DeleteDotNode::streamTo(SourceStream& s) const
465{
466 s << "delete " << DotExpr << PrecCall << m_base << "." << m_ident;
467}
468
469void DeleteValueNode::streamTo(SourceStream& s) const
470{
471 s << "delete " << PrecUnary << m_expr;
472}
473
474void VoidNode::streamTo(SourceStream& s) const
475{
476 s << "void " << PrecUnary << expr;
477}
478
479void TypeOfValueNode::streamTo(SourceStream& s) const
480{
481 s << "typeof " << PrecUnary << m_expr;
482}
483
484void TypeOfResolveNode::streamTo(SourceStream& s) const
485{
486 s << "typeof " << m_ident;
487}
488
489void PreIncResolveNode::streamTo(SourceStream& s) const
490{
491 s << "++" << m_ident;
492}
493
494void PreDecResolveNode::streamTo(SourceStream& s) const
495{
496 s << "--" << m_ident;
497}
498
499void PrefixBracketNode::streamTo(SourceStream& s) const
500{
501 if (isIncrement())
502 s << "++";
503 else
504 s << "--";
505 s << PrecCall << m_base << "[" << m_subscript << "]";
506}
507
508void PrefixDotNode::streamTo(SourceStream& s) const
509{
510 if (isIncrement())
511 s << "++";
512 else
513 s << "--";
514 s << DotExpr << PrecCall << m_base << "." << m_ident;
515}
516
517void PrefixErrorNode::streamTo(SourceStream& s) const
518{
519 if (m_oper == OpPlusPlus)
520 s << "++" << PrecUnary << m_expr;
521 else
522 s << "--" << PrecUnary << m_expr;
523}
524
525void UnaryPlusNode::streamTo(SourceStream& s) const
526{
527 s << "+ " << PrecUnary << m_expr;
528}
529
530void NegateNode::streamTo(SourceStream& s) const
531{
532 s << "- " << PrecUnary << expr;
533}
534
535void BitwiseNotNode::streamTo(SourceStream& s) const
536{
537 s << "~" << PrecUnary << expr;
538}
539
540void LogicalNotNode::streamTo(SourceStream& s) const
541{
542 s << "!" << PrecUnary << expr;
543}
544
545void MultNode::streamTo(SourceStream& s) const
546{
547 streamLeftAssociativeBinaryOperator(s, precedence(), "*", term1, term2);
548}
549
550void DivNode::streamTo(SourceStream& s) const
551{
552 streamLeftAssociativeBinaryOperator(s, precedence(), "/", term1, term2);
553}
554
555void ModNode::streamTo(SourceStream& s) const
556{
557 streamLeftAssociativeBinaryOperator(s, precedence(), "%", term1, term2);
558}
559
560void AddNode::streamTo(SourceStream& s) const
561{
562 streamLeftAssociativeBinaryOperator(s, precedence(), "+", term1, term2);
563}
564
565void SubNode::streamTo(SourceStream& s) const
566{
567 streamLeftAssociativeBinaryOperator(s, precedence(), "-", term1, term2);
568}
569
570void LeftShiftNode::streamTo(SourceStream& s) const
571{
572 streamLeftAssociativeBinaryOperator(s, precedence(), "<<", term1, term2);
573}
574
575void RightShiftNode::streamTo(SourceStream& s) const
576{
577 streamLeftAssociativeBinaryOperator(s, precedence(), ">>", term1, term2);
578}
579
580void UnsignedRightShiftNode::streamTo(SourceStream& s) const
581{
582 streamLeftAssociativeBinaryOperator(s, precedence(), ">>>", term1, term2);
583}
584
585void LessNode::streamTo(SourceStream& s) const
586{
587 streamLeftAssociativeBinaryOperator(s, precedence(), "<", expr1, expr2);
588}
589
590void GreaterNode::streamTo(SourceStream& s) const
591{
592 streamLeftAssociativeBinaryOperator(s, precedence(), ">", expr1, expr2);
593}
594
595void LessEqNode::streamTo(SourceStream& s) const
596{
597 streamLeftAssociativeBinaryOperator(s, precedence(), "<=", expr1, expr2);
598}
599
600void GreaterEqNode::streamTo(SourceStream& s) const
601{
602 streamLeftAssociativeBinaryOperator(s, precedence(), ">=", expr1, expr2);
603}
604
605void InstanceOfNode::streamTo(SourceStream& s) const
606{
607 streamLeftAssociativeBinaryOperator(s, precedence(), "instanceof", expr1, expr2);
608}
609
610void InNode::streamTo(SourceStream& s) const
611{
612 streamLeftAssociativeBinaryOperator(s, precedence(), "in", expr1, expr2);
613}
614
615void EqualNode::streamTo(SourceStream& s) const
616{
617 streamLeftAssociativeBinaryOperator(s, precedence(), "==", expr1, expr2);
618}
619
620void NotEqualNode::streamTo(SourceStream& s) const
621{
622 streamLeftAssociativeBinaryOperator(s, precedence(), "!=", expr1, expr2);
623}
624
625void StrictEqualNode::streamTo(SourceStream& s) const
626{
627 streamLeftAssociativeBinaryOperator(s, precedence(), "===", expr1, expr2);
628}
629
630void NotStrictEqualNode::streamTo(SourceStream& s) const
631{
632 streamLeftAssociativeBinaryOperator(s, precedence(), "!==", expr1, expr2);
633}
634
635void BitAndNode::streamTo(SourceStream& s) const
636{
637 streamLeftAssociativeBinaryOperator(s, precedence(), "&", expr1, expr2);
638}
639
640void BitXOrNode::streamTo(SourceStream& s) const
641{
642 streamLeftAssociativeBinaryOperator(s, precedence(), "^", expr1, expr2);
643}
644
645void BitOrNode::streamTo(SourceStream& s) const
646{
647 streamLeftAssociativeBinaryOperator(s, precedence(), "|", expr1, expr2);
648}
649
650void LogicalAndNode::streamTo(SourceStream& s) const
651{
652 streamLeftAssociativeBinaryOperator(s, precedence(), "&&", expr1, expr2);
653}
654
655void LogicalOrNode::streamTo(SourceStream& s) const
656{
657 streamLeftAssociativeBinaryOperator(s, precedence(), "||", expr1, expr2);
658}
659
660void ConditionalNode::streamTo(SourceStream& s) const
661{
662 s << PrecLogicalOr << logical
663 << " ? " << PrecAssignment << expr1
664 << " : " << PrecAssignment << expr2;
665}
666
667void ReadModifyResolveNode::streamTo(SourceStream& s) const
668{
669 s << m_ident << ' ' << operatorString(m_oper) << ' ' << PrecAssignment << m_right;
670}
671
672void AssignResolveNode::streamTo(SourceStream& s) const
673{
674 s << m_ident << " = " << PrecAssignment << m_right;
675}
676
677void ReadModifyBracketNode::streamTo(SourceStream& s) const
678{
679 s << PrecCall << m_base << '[' << m_subscript << "] "
680 << operatorString(m_oper) << ' ' << PrecAssignment << m_right;
681}
682
683void AssignBracketNode::streamTo(SourceStream& s) const
684{
685 s << PrecCall << m_base << '[' << m_subscript << "] = " << PrecAssignment << m_right;
686}
687
688void ReadModifyDotNode::streamTo(SourceStream& s) const
689{
690 s << DotExpr << PrecCall << m_base << "." << m_ident << ' '
691 << operatorString(m_oper) << ' ' << PrecAssignment << m_right;
692}
693
694void AssignDotNode::streamTo(SourceStream& s) const
695{
696 s << DotExpr << PrecCall << m_base << "." << m_ident << " = " << PrecAssignment << m_right;
697}
698
699void AssignErrorNode::streamTo(SourceStream& s) const
700{
701 s << PrecLeftHandSide << m_left << ' '
702 << operatorString(m_oper) << ' ' << PrecAssignment << m_right;
703}
704
705void CommaNode::streamTo(SourceStream& s) const
706{
707 s << PrecAssignment << expr1 << ", " << PrecAssignment << expr2;
708}
709
710void AssignExprNode::streamTo(SourceStream& s) const
711{
712 s << " = " << PrecAssignment << expr;
713}
714
715void VarDeclNode::streamTo(SourceStream& s) const
716{
717 s << "var " << ident << init;
718 for (VarDeclNode* n = next.get(); n; n = n->next.get())
719 s << ", " << ident << init;
720}
721
722void VarStatementNode::streamTo(SourceStream& s) const
723{
724 s << Endl << next << ';';
725}
726
727static inline void statementListStreamTo(const Vector<RefPtr<StatementNode> >& nodes, SourceStream& s)
728{
729 for (Vector<RefPtr<StatementNode> >::const_iterator ptr = nodes.begin(); ptr != nodes.end(); ptr++)
730 s << *ptr;
731}
732
733void BlockNode::streamTo(SourceStream& s) const
734{
735 s << Endl << "{" << Indent;
736 statementListStreamTo(m_children, s);
737 s << Unindent << Endl << "}";
738}
739
740void EmptyStatementNode::streamTo(SourceStream& s) const
741{
742 s << Endl << ';';
743}
744
745void ExprStatementNode::streamTo(SourceStream& s) const
746{
747 s << Endl << expr << ';';
748}
749
750void IfNode::streamTo(SourceStream& s) const
751{
752 s << Endl << "if (" << m_condition << ')' << Indent << m_ifBlock << Unindent;
753}
754
755void IfElseNode::streamTo(SourceStream& s) const
756{
757 IfNode::streamTo(s);
758 s << Endl << "else" << Indent << m_elseBlock << Unindent;
759}
760
761void DoWhileNode::streamTo(SourceStream& s) const
762{
763 s << Endl << "do " << Indent << statement << Unindent << Endl
764 << "while (" << expr << ");";
765}
766
767void WhileNode::streamTo(SourceStream& s) const
768{
769 s << Endl << "while (" << expr << ')' << Indent << statement << Unindent;
770}
771
772void ForNode::streamTo(SourceStream& s) const
773{
774 s << Endl << "for ("
775 << expr1
776 << "; " << expr2
777 << "; " << expr3
778 << ')' << Indent << statement << Unindent;
779}
780
781void ForInNode::streamTo(SourceStream& s) const
782{
783 s << Endl << "for (";
784 if (varDecl)
785 s << varDecl;
786 else
787 s << PrecLeftHandSide << lexpr;
788
789 s << " in " << expr << ')' << Indent << statement << Unindent;
790}
791
792void ContinueNode::streamTo(SourceStream& s) const
793{
794 s << Endl << "continue";
795 if (!ident.isNull())
796 s << ' ' << ident;
797 s << ';';
798}
799
800void BreakNode::streamTo(SourceStream& s) const
801{
802 s << Endl << "break";
803 if (!ident.isNull())
804 s << ' ' << ident;
805 s << ';';
806}
807
808void ReturnNode::streamTo(SourceStream& s) const
809{
810 s << Endl << "return";
811 if (value)
812 s << ' ' << value;
813 s << ';';
814}
815
816void WithNode::streamTo(SourceStream& s) const
817{
818 s << Endl << "with (" << expr << ") " << statement;
819}
820
821void CaseClauseNode::streamTo(SourceStream& s) const
822{
823 s << Endl;
824 if (expr)
825 s << "case " << expr;
826 else
827 s << "default";
828 s << ":" << Indent;
829 statementListStreamTo(m_children, s);
830 s << Unindent;
831}
832
833void ClauseListNode::streamTo(SourceStream& s) const
834{
835 for (const ClauseListNode* n = this; n; n = n->getNext())
836 s << n->getClause();
837}
838
839void CaseBlockNode::streamTo(SourceStream& s) const
840{
841 for (const ClauseListNode* n = list1.get(); n; n = n->getNext())
842 s << n->getClause();
843 s << def;
844 for (const ClauseListNode* n = list2.get(); n; n = n->getNext())
845 s << n->getClause();
846}
847
848void SwitchNode::streamTo(SourceStream& s) const
849{
850 s << Endl << "switch (" << expr << ") {"
851 << Indent << block << Unindent
852 << Endl << "}";
853}
854
855void LabelNode::streamTo(SourceStream& s) const
856{
857 s << Endl << label << ":" << Indent << statement << Unindent;
858}
859
860void ThrowNode::streamTo(SourceStream& s) const
861{
862 s << Endl << "throw " << expr << ';';
863}
864
865void TryNode::streamTo(SourceStream& s) const
866{
867 s << Endl << "try " << tryBlock;
868 if (catchBlock)
869 s << Endl << "catch (" << exceptionIdent << ')' << catchBlock;
870 if (finallyBlock)
871 s << Endl << "finally " << finallyBlock;
872}
873
874void ParameterNode::streamTo(SourceStream& s) const
875{
876 s << id;
877 for (ParameterNode* n = next.get(); n; n = n->next.get())
878 s << ", " << n->id;
879}
880
881void FuncDeclNode::streamTo(SourceStream& s) const
882{
883 s << Endl << "function " << ident << '(' << param << ')' << body;
884}
885
886void FuncExprNode::streamTo(SourceStream& s) const
887{
888 s << "function " << ident << '(' << param << ')' << body;
889}
890
891}
Note: See TracBrowser for help on using the repository browser.