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

Last change on this file since 31119 was 30944, checked in by [email protected], 17 years ago

Reviewed by NOBODY.

Build fix for JSC on windows.

  • API/JSStringRefCF.cpp: (JSStringCreateWithCFString):
  • kjs/function.cpp: (KJS::decode):
  • kjs/nodes2string.cpp: (KJS::escapeStringForPrettyPrinting):
  • Property svn:eol-style set to native
File size: 23.4 KB
Line 
1/*
2 * Copyright (C) 2002 Harri Porten ([email protected])
3 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 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()
45 : m_numberNeedsParens(false)
46 , m_atStartOfStatement(true)
47 , m_precedence(PrecExpression)
48 {
49 }
50
51 UString toString() const { return m_string; }
52
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(); }
65
66private:
67 UString m_string;
68 UString m_spacesForIndentation;
69 bool m_numberNeedsParens;
70 bool m_atStartOfStatement;
71 Precedence m_precedence;
72};
73
74// --------
75
76static UString escapeStringForPrettyPrinting(const UString& s)
77{
78 UString escapedString;
79
80 for (int i = 0; i < s.size(); i++) {
81 UChar c = s.data()[i];
82 switch (c) {
83 case '\"':
84 escapedString += "\\\"";
85 break;
86 case '\n':
87 escapedString += "\\n";
88 break;
89 case '\r':
90 escapedString += "\\r";
91 break;
92 case '\t':
93 escapedString += "\\t";
94 break;
95 case '\\':
96 escapedString += "\\\\";
97 break;
98 default:
99 if (c < 128 && isPrintableChar(c))
100 escapedString.append(c);
101 else {
102 char hexValue[7];
103 snprintf(hexValue, 7, "\\u%04x", c);
104 escapedString += hexValue;
105 }
106 }
107 }
108
109 return escapedString;
110}
111
112static const char* operatorString(Operator oper)
113{
114 switch (oper) {
115 case OpEqual:
116 return "=";
117 case OpMultEq:
118 return "*=";
119 case OpDivEq:
120 return "/=";
121 case OpPlusEq:
122 return "+=";
123 case OpMinusEq:
124 return "-=";
125 case OpLShift:
126 return "<<=";
127 case OpRShift:
128 return ">>=";
129 case OpURShift:
130 return ">>>=";
131 case OpAndEq:
132 return "&=";
133 case OpXOrEq:
134 return "^=";
135 case OpOrEq:
136 return "|=";
137 case OpModEq:
138 return "%=";
139 case OpPlusPlus:
140 return "++";
141 case OpMinusMinus:
142 return "--";
143 }
144 ASSERT_NOT_REACHED();
145 return "???";
146}
147
148static bool isParserRoundTripNumber(const UString& string)
149{
150 double number = string.toDouble(false, false);
151 if (isnan(number) || isinf(number))
152 return false;
153 return string == UString::from(number);
154}
155
156// --------
157
158SourceStream& SourceStream::operator<<(char c)
159{
160 m_numberNeedsParens = false;
161 m_atStartOfStatement = false;
162 // use unsigned char to zero-extend instead of sign-extend
163 UChar ch(static_cast<unsigned char>(c));
164 m_string.append(ch);
165 return *this;
166}
167
168SourceStream& SourceStream::operator<<(const char* s)
169{
170 m_numberNeedsParens = false;
171 m_atStartOfStatement = false;
172 m_string += s;
173 return *this;
174}
175
176SourceStream& SourceStream::operator<<(double value)
177{
178 bool needParens = m_numberNeedsParens;
179 m_numberNeedsParens = false;
180 m_atStartOfStatement = false;
181
182 if (needParens)
183 m_string.append('(');
184 m_string += UString::from(value);
185 if (needParens)
186 m_string.append(')');
187
188 return *this;
189}
190
191SourceStream& SourceStream::operator<<(const UString& s)
192{
193 m_numberNeedsParens = false;
194 m_atStartOfStatement = false;
195 m_string += s;
196 return *this;
197}
198
199SourceStream& SourceStream::operator<<(const Identifier& s)
200{
201 m_numberNeedsParens = false;
202 m_atStartOfStatement = false;
203 m_string += s.ustring();
204 return *this;
205}
206
207SourceStream& SourceStream::operator<<(const Node* n)
208{
209 bool needParens = (m_precedence != PrecExpression && n->precedence() > m_precedence) || (m_atStartOfStatement && n->needsParensIfLeftmost());
210 m_precedence = PrecExpression;
211 if (!n)
212 return *this;
213 if (needParens) {
214 m_numberNeedsParens = false;
215 m_string.append('(');
216 }
217 n->streamTo(*this);
218 if (needParens)
219 m_string.append(')');
220 return *this;
221}
222
223SourceStream& SourceStream::operator<<(EndlType)
224{
225 m_numberNeedsParens = false;
226 m_atStartOfStatement = true;
227 m_string.append('\n');
228 m_string.append(m_spacesForIndentation);
229 return *this;
230}
231
232SourceStream& SourceStream::operator<<(IndentType)
233{
234 m_numberNeedsParens = false;
235 m_atStartOfStatement = false;
236 m_spacesForIndentation += " ";
237 return *this;
238}
239
240SourceStream& SourceStream::operator<<(UnindentType)
241{
242 m_numberNeedsParens = false;
243 m_atStartOfStatement = false;
244 m_spacesForIndentation = m_spacesForIndentation.substr(0, m_spacesForIndentation.size() - 2);
245 return *this;
246}
247
248inline SourceStream& SourceStream::operator<<(DotExprType)
249{
250 m_numberNeedsParens = true;
251 return *this;
252}
253
254inline SourceStream& SourceStream::operator<<(Precedence precedence)
255{
256 m_precedence = precedence;
257 return *this;
258}
259
260static void streamLeftAssociativeBinaryOperator(SourceStream& s, Precedence precedence,
261 const char* operatorString, const Node* left, const Node* right)
262{
263 s << precedence << left
264 << ' ' << operatorString << ' '
265 << static_cast<Precedence>(precedence - 1) << right;
266}
267
268template <typename T> static inline void streamLeftAssociativeBinaryOperator(SourceStream& s,
269 Precedence p, const char* o, const RefPtr<T>& l, const RefPtr<T>& r)
270{
271 streamLeftAssociativeBinaryOperator(s, p, o, l.get(), r.get());
272}
273
274static inline void bracketNodeStreamTo(SourceStream& s, const RefPtr<ExpressionNode>& base, const RefPtr<ExpressionNode>& subscript)
275{
276 s << PrecCall << base.get() << "[" << subscript.get() << "]";
277}
278
279static inline void dotNodeStreamTo(SourceStream& s, const RefPtr<ExpressionNode>& base, const Identifier& ident)
280{
281 s << DotExpr << PrecCall << base.get() << "." << ident;
282}
283
284// --------
285
286UString Node::toString() const
287{
288 SourceStream stream;
289 streamTo(stream);
290 return stream.toString();
291}
292
293// --------
294
295void NullNode::streamTo(SourceStream& s) const
296{
297 s << "null";
298}
299
300void FalseNode::streamTo(SourceStream& s) const
301{
302 s << "false";
303}
304
305void TrueNode::streamTo(SourceStream& s) const
306{
307 s << "true";
308}
309
310void PlaceholderTrueNode::streamTo(SourceStream&) const
311{
312}
313
314void NumberNode::streamTo(SourceStream& s) const
315{
316 s << value();
317}
318
319void StringNode::streamTo(SourceStream& s) const
320{
321 s << '"' << escapeStringForPrettyPrinting(m_value) << '"';
322}
323
324void RegExpNode::streamTo(SourceStream& s) const
325{
326 s << '/' << m_regExp->pattern() << '/' << m_regExp->flags();
327}
328
329void ThisNode::streamTo(SourceStream& s) const
330{
331 s << "this";
332}
333
334void ResolveNode::streamTo(SourceStream& s) const
335{
336 s << m_ident;
337}
338
339void ElementNode::streamTo(SourceStream& s) const
340{
341 for (const ElementNode* n = this; n; n = n->m_next.get()) {
342 for (int i = 0; i < n->m_elision; i++)
343 s << ',';
344 s << PrecAssignment << n->m_node;
345 if (n->m_next)
346 s << ',';
347 }
348}
349
350void ArrayNode::streamTo(SourceStream& s) const
351{
352 s << '[' << m_element;
353 for (int i = 0; i < m_elision; i++)
354 s << ',';
355 // Parser consumes one elision comma if there's array elements
356 // present in the expression.
357 if (m_optional && m_element)
358 s << ',';
359 s << ']';
360}
361
362void ObjectLiteralNode::streamTo(SourceStream& s) const
363{
364 if (m_list)
365 s << "{ " << m_list << " }";
366 else
367 s << "{ }";
368}
369
370void PropertyListNode::streamTo(SourceStream& s) const
371{
372 s << m_node;
373 for (const PropertyListNode* n = m_next.get(); n; n = n->m_next.get())
374 s << ", " << n->m_node;
375}
376
377void PropertyNode::streamTo(SourceStream& s) const
378{
379 switch (m_type) {
380 case Constant: {
381 UString propertyName = name().ustring();
382 if (isParserRoundTripNumber(propertyName))
383 s << propertyName;
384 else
385 s << '"' << escapeStringForPrettyPrinting(propertyName) << '"';
386 s << ": " << PrecAssignment << m_assign;
387 break;
388 }
389 case Getter:
390 case Setter: {
391 const FuncExprNode* func = static_cast<const FuncExprNode*>(m_assign.get());
392 if (m_type == Getter)
393 s << "get ";
394 else
395 s << "set ";
396 s << escapeStringForPrettyPrinting(name().ustring())
397 << "(" << func->m_parameter << ')' << func->m_body;
398 break;
399 }
400 }
401}
402
403void BracketAccessorNode::streamTo(SourceStream& s) const
404{
405 bracketNodeStreamTo(s, m_base, m_subscript);
406}
407
408void DotAccessorNode::streamTo(SourceStream& s) const
409{
410 dotNodeStreamTo(s, m_base, m_ident);
411}
412
413void ArgumentListNode::streamTo(SourceStream& s) const
414{
415 s << PrecAssignment << m_expr;
416 for (ArgumentListNode* n = m_next.get(); n; n = n->m_next.get())
417 s << ", " << PrecAssignment << n->m_expr;
418}
419
420void ArgumentsNode::streamTo(SourceStream& s) const
421{
422 s << '(' << m_listNode << ')';
423}
424
425void NewExprNode::streamTo(SourceStream& s) const
426{
427 s << "new " << PrecMember << m_expr << m_args;
428}
429
430void EvalFunctionCallNode::streamTo(SourceStream& s) const
431{
432 s << "eval" << m_args;
433}
434
435void FunctionCallValueNode::streamTo(SourceStream& s) const
436{
437 s << PrecCall << m_expr << m_args;
438}
439
440void FunctionCallResolveNode::streamTo(SourceStream& s) const
441{
442 s << m_ident << m_args;
443}
444
445void FunctionCallBracketNode::streamTo(SourceStream& s) const
446{
447 bracketNodeStreamTo(s, m_base, m_subscript);
448 s << m_args;
449}
450
451void FunctionCallDotNode::streamTo(SourceStream& s) const
452{
453 dotNodeStreamTo(s, m_base, m_ident);
454 s << m_args;
455}
456
457void PostIncResolveNode::streamTo(SourceStream& s) const
458{
459 s << m_ident << "++";
460}
461
462void PostDecResolveNode::streamTo(SourceStream& s) const
463{
464 s << m_ident << "--";
465}
466
467void PostIncBracketNode::streamTo(SourceStream& s) const
468{
469 bracketNodeStreamTo(s, m_base, m_subscript);
470 s << "++";
471}
472
473void PostDecBracketNode::streamTo(SourceStream& s) const
474{
475 bracketNodeStreamTo(s, m_base, m_subscript);
476 s << "--";
477}
478
479void PostIncDotNode::streamTo(SourceStream& s) const
480{
481 dotNodeStreamTo(s, m_base, m_ident);
482 s << "++";
483}
484
485void PostDecDotNode::streamTo(SourceStream& s) const
486{
487 dotNodeStreamTo(s, m_base, m_ident);
488 s << "--";
489}
490
491void PostfixErrorNode::streamTo(SourceStream& s) const
492{
493 s << PrecLeftHandSide << m_expr;
494 if (m_operator == OpPlusPlus)
495 s << "++";
496 else
497 s << "--";
498}
499
500void DeleteResolveNode::streamTo(SourceStream& s) const
501{
502 s << "delete " << m_ident;
503}
504
505void DeleteBracketNode::streamTo(SourceStream& s) const
506{
507 s << "delete ";
508 bracketNodeStreamTo(s, m_base, m_subscript);
509}
510
511void DeleteDotNode::streamTo(SourceStream& s) const
512{
513 s << "delete ";
514 dotNodeStreamTo(s, m_base, m_ident);
515}
516
517void DeleteValueNode::streamTo(SourceStream& s) const
518{
519 s << "delete " << PrecUnary << m_expr;
520}
521
522void VoidNode::streamTo(SourceStream& s) const
523{
524 s << "void " << PrecUnary << m_expr;
525}
526
527void TypeOfValueNode::streamTo(SourceStream& s) const
528{
529 s << "typeof " << PrecUnary << m_expr;
530}
531
532void TypeOfResolveNode::streamTo(SourceStream& s) const
533{
534 s << "typeof " << m_ident;
535}
536
537void PreIncResolveNode::streamTo(SourceStream& s) const
538{
539 s << "++" << m_ident;
540}
541
542void PreDecResolveNode::streamTo(SourceStream& s) const
543{
544 s << "--" << m_ident;
545}
546
547void PreIncBracketNode::streamTo(SourceStream& s) const
548{
549 s << "++";
550 bracketNodeStreamTo(s, m_base, m_subscript);
551}
552
553void PreDecBracketNode::streamTo(SourceStream& s) const
554{
555 s << "--";
556 bracketNodeStreamTo(s, m_base, m_subscript);
557}
558
559void PreIncDotNode::streamTo(SourceStream& s) const
560{
561 s << "++";
562 dotNodeStreamTo(s, m_base, m_ident);
563}
564
565void PreDecDotNode::streamTo(SourceStream& s) const
566{
567 s << "--";
568 dotNodeStreamTo(s, m_base, m_ident);
569}
570
571void PrefixErrorNode::streamTo(SourceStream& s) const
572{
573 if (m_operator == OpPlusPlus)
574 s << "++" << PrecUnary << m_expr;
575 else
576 s << "--" << PrecUnary << m_expr;
577}
578
579void UnaryPlusNode::streamTo(SourceStream& s) const
580{
581 s << "+ " << PrecUnary << m_expr;
582}
583
584void NegateNode::streamTo(SourceStream& s) const
585{
586 s << "- " << PrecUnary << m_expr;
587}
588
589void BitwiseNotNode::streamTo(SourceStream& s) const
590{
591 s << "~" << PrecUnary << m_expr;
592}
593
594void LogicalNotNode::streamTo(SourceStream& s) const
595{
596 s << "!" << PrecUnary << m_expr;
597}
598
599void MultNode::streamTo(SourceStream& s) const
600{
601 streamLeftAssociativeBinaryOperator(s, precedence(), "*", m_term1, m_term2);
602}
603
604void DivNode::streamTo(SourceStream& s) const
605{
606 streamLeftAssociativeBinaryOperator(s, precedence(), "/", m_term1, m_term2);
607}
608
609void ModNode::streamTo(SourceStream& s) const
610{
611 streamLeftAssociativeBinaryOperator(s, precedence(), "%", m_term1, m_term2);
612}
613
614void AddNode::streamTo(SourceStream& s) const
615{
616 streamLeftAssociativeBinaryOperator(s, precedence(), "+", m_term1, m_term2);
617}
618
619void SubNode::streamTo(SourceStream& s) const
620{
621 streamLeftAssociativeBinaryOperator(s, precedence(), "-", m_term1, m_term2);
622}
623
624void LeftShiftNode::streamTo(SourceStream& s) const
625{
626 streamLeftAssociativeBinaryOperator(s, precedence(), "<<", m_term1, m_term2);
627}
628
629void RightShiftNode::streamTo(SourceStream& s) const
630{
631 streamLeftAssociativeBinaryOperator(s, precedence(), ">>", m_term1, m_term2);
632}
633
634void UnsignedRightShiftNode::streamTo(SourceStream& s) const
635{
636 streamLeftAssociativeBinaryOperator(s, precedence(), ">>>", m_term1, m_term2);
637}
638
639void LessNode::streamTo(SourceStream& s) const
640{
641 streamLeftAssociativeBinaryOperator(s, precedence(), "<", m_expr1, m_expr2);
642}
643
644void GreaterNode::streamTo(SourceStream& s) const
645{
646 streamLeftAssociativeBinaryOperator(s, precedence(), ">", m_expr1, m_expr2);
647}
648
649void LessEqNode::streamTo(SourceStream& s) const
650{
651 streamLeftAssociativeBinaryOperator(s, precedence(), "<=", m_expr1, m_expr2);
652}
653
654void GreaterEqNode::streamTo(SourceStream& s) const
655{
656 streamLeftAssociativeBinaryOperator(s, precedence(), ">=", m_expr1, m_expr2);
657}
658
659void InstanceOfNode::streamTo(SourceStream& s) const
660{
661 streamLeftAssociativeBinaryOperator(s, precedence(), "instanceof", m_expr1, m_expr2);
662}
663
664void InNode::streamTo(SourceStream& s) const
665{
666 streamLeftAssociativeBinaryOperator(s, precedence(), "in", m_expr1, m_expr2);
667}
668
669void EqualNode::streamTo(SourceStream& s) const
670{
671 streamLeftAssociativeBinaryOperator(s, precedence(), "==", m_expr1, m_expr2);
672}
673
674void NotEqualNode::streamTo(SourceStream& s) const
675{
676 streamLeftAssociativeBinaryOperator(s, precedence(), "!=", m_expr1, m_expr2);
677}
678
679void StrictEqualNode::streamTo(SourceStream& s) const
680{
681 streamLeftAssociativeBinaryOperator(s, precedence(), "===", m_expr1, m_expr2);
682}
683
684void NotStrictEqualNode::streamTo(SourceStream& s) const
685{
686 streamLeftAssociativeBinaryOperator(s, precedence(), "!==", m_expr1, m_expr2);
687}
688
689void BitAndNode::streamTo(SourceStream& s) const
690{
691 streamLeftAssociativeBinaryOperator(s, precedence(), "&", m_expr1, m_expr2);
692}
693
694void BitXOrNode::streamTo(SourceStream& s) const
695{
696 streamLeftAssociativeBinaryOperator(s, precedence(), "^", m_expr1, m_expr2);
697}
698
699void BitOrNode::streamTo(SourceStream& s) const
700{
701 streamLeftAssociativeBinaryOperator(s, precedence(), "|", m_expr1, m_expr2);
702}
703
704void LogicalAndNode::streamTo(SourceStream& s) const
705{
706 streamLeftAssociativeBinaryOperator(s, precedence(), "&&", m_expr1, m_expr2);
707}
708
709void LogicalOrNode::streamTo(SourceStream& s) const
710{
711 streamLeftAssociativeBinaryOperator(s, precedence(), "||", m_expr1, m_expr2);
712}
713
714void ConditionalNode::streamTo(SourceStream& s) const
715{
716 s << PrecLogicalOr << m_logical
717 << " ? " << PrecAssignment << m_expr1
718 << " : " << PrecAssignment << m_expr2;
719}
720
721void ReadModifyResolveNode::streamTo(SourceStream& s) const
722{
723 s << m_ident << ' ' << operatorString(m_operator) << ' ' << PrecAssignment << m_right;
724}
725
726void AssignResolveNode::streamTo(SourceStream& s) const
727{
728 s << m_ident << " = " << PrecAssignment << m_right;
729}
730
731void ReadModifyBracketNode::streamTo(SourceStream& s) const
732{
733 bracketNodeStreamTo(s, m_base, m_subscript);
734 s << ' ' << operatorString(m_operator) << ' ' << PrecAssignment << m_right;
735}
736
737void AssignBracketNode::streamTo(SourceStream& s) const
738{
739 bracketNodeStreamTo(s, m_base, m_subscript);
740 s << " = " << PrecAssignment << m_right;
741}
742
743void ReadModifyDotNode::streamTo(SourceStream& s) const
744{
745 dotNodeStreamTo(s, m_base, m_ident);
746 s << ' ' << operatorString(m_operator) << ' ' << PrecAssignment << m_right;
747}
748
749void AssignDotNode::streamTo(SourceStream& s) const
750{
751 dotNodeStreamTo(s, m_base, m_ident);
752 s << " = " << PrecAssignment << m_right;
753}
754
755void AssignErrorNode::streamTo(SourceStream& s) const
756{
757 s << PrecLeftHandSide << m_left << ' '
758 << operatorString(m_operator) << ' ' << PrecAssignment << m_right;
759}
760
761void CommaNode::streamTo(SourceStream& s) const
762{
763 s << PrecAssignment << m_expr1 << ", " << PrecAssignment << m_expr2;
764}
765
766void ConstDeclNode::streamTo(SourceStream& s) const
767{
768 s << m_ident;
769 if (m_init)
770 s << " = " << m_init;
771 for (ConstDeclNode* n = m_next.get(); n; n = n->m_next.get()) {
772 s << ", " << m_ident;
773 if (m_init)
774 s << " = " << m_init;
775 }
776}
777
778void ConstStatementNode::streamTo(SourceStream& s) const
779{
780 s << Endl << "const " << m_next << ';';
781}
782
783static inline void statementListStreamTo(const Vector<RefPtr<StatementNode> >& nodes, SourceStream& s)
784{
785 for (Vector<RefPtr<StatementNode> >::const_iterator ptr = nodes.begin(); ptr != nodes.end(); ptr++)
786 s << *ptr;
787}
788
789void BlockNode::streamTo(SourceStream& s) const
790{
791 s << Endl << "{" << Indent;
792 statementListStreamTo(m_children, s);
793 s << Unindent << Endl << "}";
794}
795
796void ScopeNode::streamTo(SourceStream& s) const
797{
798 s << Endl << "{" << Indent;
799
800 bool printedVar = false;
801 for (size_t i = 0; i < m_varStack.size(); ++i) {
802 if (m_varStack[i].second == 0) {
803 if (!printedVar) {
804 s << Endl << "var ";
805 printedVar = true;
806 } else
807 s << ", ";
808 s << m_varStack[i].first;
809 }
810 }
811 if (printedVar)
812 s << ';';
813
814 statementListStreamTo(m_children, s);
815 s << Unindent << Endl << "}";
816}
817
818void EmptyStatementNode::streamTo(SourceStream& s) const
819{
820 s << Endl << ';';
821}
822
823void ExprStatementNode::streamTo(SourceStream& s) const
824{
825 s << Endl << m_expr << ';';
826}
827
828void VarStatementNode::streamTo(SourceStream& s) const
829{
830 s << Endl << "var " << m_expr << ';';
831}
832
833void IfNode::streamTo(SourceStream& s) const
834{
835 s << Endl << "if (" << m_condition << ')' << Indent << m_ifBlock << Unindent;
836}
837
838void IfElseNode::streamTo(SourceStream& s) const
839{
840 IfNode::streamTo(s);
841 s << Endl << "else" << Indent << m_elseBlock << Unindent;
842}
843
844void DoWhileNode::streamTo(SourceStream& s) const
845{
846 s << Endl << "do " << Indent << m_statement << Unindent << Endl
847 << "while (" << m_expr << ");";
848}
849
850void WhileNode::streamTo(SourceStream& s) const
851{
852 s << Endl << "while (" << m_expr << ')' << Indent << m_statement << Unindent;
853}
854
855void ForNode::streamTo(SourceStream& s) const
856{
857 s << Endl << "for ("
858 << (m_expr1WasVarDecl ? "var " : "")
859 << m_expr1
860 << "; " << m_expr2
861 << "; " << m_expr3
862 << ')' << Indent << m_statement << Unindent;
863}
864
865void ForInNode::streamTo(SourceStream& s) const
866{
867 s << Endl << "for (";
868 if (m_identIsVarDecl) {
869 s << "var ";
870 if (m_init)
871 s << m_init;
872 else
873 s << PrecLeftHandSide << m_lexpr;
874 } else
875 s << PrecLeftHandSide << m_lexpr;
876
877 s << " in " << m_expr << ')' << Indent << m_statement << Unindent;
878}
879
880void ContinueNode::streamTo(SourceStream& s) const
881{
882 s << Endl << "continue";
883 if (!m_ident.isNull())
884 s << ' ' << m_ident;
885 s << ';';
886}
887
888void BreakNode::streamTo(SourceStream& s) const
889{
890 s << Endl << "break";
891 if (!m_ident.isNull())
892 s << ' ' << m_ident;
893 s << ';';
894}
895
896void ReturnNode::streamTo(SourceStream& s) const
897{
898 s << Endl << "return";
899 if (m_value)
900 s << ' ' << m_value;
901 s << ';';
902}
903
904void WithNode::streamTo(SourceStream& s) const
905{
906 s << Endl << "with (" << m_expr << ") " << m_statement;
907}
908
909void CaseClauseNode::streamTo(SourceStream& s) const
910{
911 s << Endl;
912 if (m_expr)
913 s << "case " << m_expr;
914 else
915 s << "default";
916 s << ":" << Indent;
917 statementListStreamTo(m_children, s);
918 s << Unindent;
919}
920
921void ClauseListNode::streamTo(SourceStream& s) const
922{
923 for (const ClauseListNode* n = this; n; n = n->getNext())
924 s << n->getClause();
925}
926
927void CaseBlockNode::streamTo(SourceStream& s) const
928{
929 for (const ClauseListNode* n = m_list1.get(); n; n = n->getNext())
930 s << n->getClause();
931 s << m_defaultClause;
932 for (const ClauseListNode* n = m_list2.get(); n; n = n->getNext())
933 s << n->getClause();
934}
935
936void SwitchNode::streamTo(SourceStream& s) const
937{
938 s << Endl << "switch (" << m_expr << ") {"
939 << Indent << m_block << Unindent
940 << Endl << "}";
941}
942
943void LabelNode::streamTo(SourceStream& s) const
944{
945 s << Endl << m_label << ":" << Indent << m_statement << Unindent;
946}
947
948void ThrowNode::streamTo(SourceStream& s) const
949{
950 s << Endl << "throw " << m_expr << ';';
951}
952
953void TryNode::streamTo(SourceStream& s) const
954{
955 s << Endl << "try " << m_tryBlock;
956 if (m_catchBlock)
957 s << Endl << "catch (" << m_exceptionIdent << ')' << m_catchBlock;
958 if (m_finallyBlock)
959 s << Endl << "finally " << m_finallyBlock;
960}
961
962void ParameterNode::streamTo(SourceStream& s) const
963{
964 s << m_ident;
965 for (ParameterNode* n = m_next.get(); n; n = n->m_next.get())
966 s << ", " << n->m_ident;
967}
968
969void FuncDeclNode::streamTo(SourceStream& s) const
970{
971 s << Endl << "function " << m_ident << '(' << m_parameter << ')' << m_body;
972}
973
974void FuncExprNode::streamTo(SourceStream& s) const
975{
976 s << "function " << m_ident << '(' << m_parameter << ')' << m_body;
977}
978
979} // namespace KJS
Note: See TracBrowser for help on using the repository browser.