2 * This file is part of the KDE libraries
3 * Copyright (C) 2002 Harri Porten (porten@kde.org)
4 * Copyright (C) 2003 Apple Computer, Inc.
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.
29 * A simple text streaming class that helps with code indentation.
34 Endl, Indent, Unindent
37 UString toString() const { return str; }
38 SourceStream& operator<<(const Identifier &);
39 SourceStream& operator<<(const UString &);
40 SourceStream& operator<<(const char *);
41 SourceStream& operator<<(char);
42 SourceStream& operator<<(Format f);
43 SourceStream& operator<<(const Node *);
44 template <typename T> SourceStream& operator<<(RefPtr<T> n) { return this->operator<<(n.get()); }
46 UString str; /* TODO: buffer */
53 SourceStream& SourceStream::operator<<(char c)
59 SourceStream& SourceStream::operator<<(const char *s)
65 SourceStream& SourceStream::operator<<(const UString &s)
71 SourceStream& SourceStream::operator<<(const Identifier &s)
77 SourceStream& SourceStream::operator<<(const Node *n)
84 SourceStream& SourceStream::operator<<(Format f)
94 ind = ind.substr(0, ind.size() - 2);
101 UString Node::toString() const
106 return str.toString();
109 void NullNode::streamTo(SourceStream &s) const { s << "null"; }
111 void BooleanNode::streamTo(SourceStream &s) const
113 s << (value ? "true" : "false");
116 void NumberNode::streamTo(SourceStream &s) const { s << UString::from(value); }
118 void StringNode::streamTo(SourceStream &s) const
120 s << '"' << escapeStringForPrettyPrinting(value) << '"';
123 void RegExpNode::streamTo(SourceStream &s) const
125 s << "/" << pattern << "/" << flags;
128 void ThisNode::streamTo(SourceStream &s) const { s << "this"; }
130 void ResolveNode::streamTo(SourceStream &s) const { s << ident; }
132 void GroupNode::streamTo(SourceStream &s) const
134 s << "(" << group << ")";
137 void ElementNode::streamTo(SourceStream &s) const
139 for (const ElementNode *n = this; n; n = n->next.get()) {
140 for (int i = 0; i < n->elision; i++)
146 void ArrayNode::streamTo(SourceStream &s) const
149 for (int i = 0; i < elision; i++)
154 void ObjectLiteralNode::streamTo(SourceStream &s) const
157 s << "{ " << list << " }";
162 void PropertyListNode::streamTo(SourceStream &s) const
166 for (const PropertyListNode *n = next.get(); n; n = n->next.get())
167 s << ", " << n->node;
170 void PropertyNode::streamTo(SourceStream &s) const
174 s << name << ": " << assign;
178 const FuncExprNode *func = static_cast<const FuncExprNode *>(assign.get());
184 s << name << "(" << func->param << ")" << func->body;
190 void PropertyNameNode::streamTo(SourceStream &s) const
193 s << UString::from(numeric);
198 void BracketAccessorNode::streamTo(SourceStream &s) const
200 s << expr1 << "[" << expr2 << "]";
203 void DotAccessorNode::streamTo(SourceStream &s) const
205 s << expr << "." << ident;
208 void ArgumentListNode::streamTo(SourceStream &s) const
211 for (ArgumentListNode *n = next.get(); n; n = n->next.get())
212 s << ", " << n->expr;
215 void ArgumentsNode::streamTo(SourceStream &s) const
217 s << "(" << list << ")";
220 void NewExprNode::streamTo(SourceStream &s) const
222 s << "new " << expr << args;
225 void FunctionCallValueNode::streamTo(SourceStream &s) const
230 void FunctionCallResolveNode::streamTo(SourceStream &s) const
235 void FunctionCallBracketNode::streamTo(SourceStream &s) const
237 s << base << "[" << subscript << "]" << args;
240 void FunctionCallParenBracketNode::streamTo(SourceStream &s) const
242 s << "(" << base << "[" << subscript << "])" << args;
245 void FunctionCallDotNode::streamTo(SourceStream &s) const
247 s << base << "." << ident << args;
250 void FunctionCallParenDotNode::streamTo(SourceStream &s) const
252 s << "(" << base << "." << ident << ")" << args;
255 void PostfixResolveNode::streamTo(SourceStream &s) const
258 if (m_oper == OpPlusPlus)
264 void PostfixBracketNode::streamTo(SourceStream &s) const
266 s << m_base << "[" << m_subscript << "]";
267 if (m_oper == OpPlusPlus)
273 void PostfixDotNode::streamTo(SourceStream &s) const
275 s << m_base << "." << m_ident;
276 if (m_oper == OpPlusPlus)
282 void DeleteResolveNode::streamTo(SourceStream &s) const
284 s << "delete " << m_ident;
287 void DeleteBracketNode::streamTo(SourceStream &s) const
289 s << "delete " << m_base << "[" << m_subscript << "]";
292 void DeleteDotNode::streamTo(SourceStream &s) const
294 s << "delete " << m_base << "." << m_ident;
297 void DeleteValueNode::streamTo(SourceStream &s) const
299 s << "delete " << m_expr;
302 void VoidNode::streamTo(SourceStream &s) const
304 s << "void " << expr;
307 void TypeOfValueNode::streamTo(SourceStream &s) const
309 s << "typeof " << m_expr;
312 void TypeOfResolveNode::streamTo(SourceStream &s) const
314 s << "typeof " << m_ident;
317 void PrefixResolveNode::streamTo(SourceStream &s) const
319 if (m_oper == OpPlusPlus)
326 void PrefixBracketNode::streamTo(SourceStream &s) const
328 if (m_oper == OpPlusPlus)
332 s << m_base << "[" << m_subscript << "]";
335 void PrefixDotNode::streamTo(SourceStream &s) const
337 if (m_oper == OpPlusPlus)
341 s << m_base << "." << m_ident;
344 void UnaryPlusNode::streamTo(SourceStream &s) const
349 void NegateNode::streamTo(SourceStream &s) const
354 void BitwiseNotNode::streamTo(SourceStream &s) const
359 void LogicalNotNode::streamTo(SourceStream &s) const
364 void MultNode::streamTo(SourceStream &s) const
366 s << term1 << oper << term2;
369 void AddNode::streamTo(SourceStream &s) const
371 s << term1 << oper << term2;
374 void ShiftNode::streamTo(SourceStream &s) const
377 if (oper == OpLShift)
379 else if (oper == OpRShift)
386 void RelationalNode::streamTo(SourceStream &s) const
414 void EqualNode::streamTo(SourceStream &s) const
436 void BitOperNode::streamTo(SourceStream &s) const
439 if (oper == OpBitAnd)
441 else if (oper == OpBitXOr)
448 void BinaryLogicalNode::streamTo(SourceStream &s) const
450 s << expr1 << (oper == OpAnd ? " && " : " || ") << expr2;
453 void ConditionalNode::streamTo(SourceStream &s) const
455 s << logical << " ? " << expr1 << " : " << expr2;
458 static void streamAssignmentOperatorTo(SourceStream &s, Operator oper)
504 void AssignResolveNode::streamTo(SourceStream &s) const
507 streamAssignmentOperatorTo(s, m_oper);
511 void AssignBracketNode::streamTo(SourceStream &s) const
513 s << m_base << "[" << m_subscript << "]";
514 streamAssignmentOperatorTo(s, m_oper);
518 void AssignDotNode::streamTo(SourceStream &s) const
520 s << m_base << "." << m_ident;
521 streamAssignmentOperatorTo(s, m_oper);
525 void CommaNode::streamTo(SourceStream &s) const
527 s << expr1 << ", " << expr2;
530 void AssignExprNode::streamTo(SourceStream &s) const
535 void VarDeclNode::streamTo(SourceStream &s) const
540 void VarDeclListNode::streamTo(SourceStream &s) const
543 for (VarDeclListNode *n = next.get(); n; n = n->next.get())
547 void VarStatementNode::streamTo(SourceStream &s) const
549 s << SourceStream::Endl << "var " << next << ";";
552 void BlockNode::streamTo(SourceStream &s) const
554 s << SourceStream::Endl << "{" << SourceStream::Indent
555 << source << SourceStream::Unindent << SourceStream::Endl << "}";
558 void EmptyStatementNode::streamTo(SourceStream &s) const
560 s << SourceStream::Endl << ";";
563 void ExprStatementNode::streamTo(SourceStream &s) const
565 s << SourceStream::Endl << expr << ";";
568 void IfNode::streamTo(SourceStream &s) const
570 s << SourceStream::Endl << "if (" << expr << ")" << SourceStream::Indent
571 << statement1 << SourceStream::Unindent;
573 s << SourceStream::Endl << "else" << SourceStream::Indent
574 << statement2 << SourceStream::Unindent;
577 void DoWhileNode::streamTo(SourceStream &s) const
579 s << SourceStream::Endl << "do " << SourceStream::Indent
580 << statement << SourceStream::Unindent << SourceStream::Endl
581 << "while (" << expr << ");";
584 void WhileNode::streamTo(SourceStream &s) const
586 s << SourceStream::Endl << "while (" << expr << ")" << SourceStream::Indent
587 << statement << SourceStream::Unindent;
590 void ForNode::streamTo(SourceStream &s) const
592 s << SourceStream::Endl << "for ("
593 << expr1 // TODO: doesn't properly do "var i = 0"
596 << ")" << SourceStream::Indent << statement << SourceStream::Unindent;
599 void ForInNode::streamTo(SourceStream &s) const
601 s << SourceStream::Endl << "for (";
603 s << "var " << varDecl;
609 s << " in " << expr << ")" << SourceStream::Indent
610 << statement << SourceStream::Unindent;
613 void ContinueNode::streamTo(SourceStream &s) const
615 s << SourceStream::Endl << "continue";
621 void BreakNode::streamTo(SourceStream &s) const
623 s << SourceStream::Endl << "break";
629 void ReturnNode::streamTo(SourceStream &s) const
631 s << SourceStream::Endl << "return";
637 void WithNode::streamTo(SourceStream &s) const
639 s << SourceStream::Endl << "with (" << expr << ") "
643 void CaseClauseNode::streamTo(SourceStream &s) const
645 s << SourceStream::Endl;
647 s << "case " << expr;
650 s << ":" << SourceStream::Indent;
653 s << SourceStream::Unindent;
656 void ClauseListNode::streamTo(SourceStream &s) const
658 for (const ClauseListNode *n = this; n; n = n->getNext())
662 void CaseBlockNode::streamTo(SourceStream &s) const
664 for (const ClauseListNode *n = list1.get(); n; n = n->getNext())
668 for (const ClauseListNode *n = list2.get(); n; n = n->getNext())
672 void SwitchNode::streamTo(SourceStream &s) const
674 s << SourceStream::Endl << "switch (" << expr << ") {"
675 << SourceStream::Indent << block << SourceStream::Unindent
676 << SourceStream::Endl << "}";
679 void LabelNode::streamTo(SourceStream &s) const
681 s << SourceStream::Endl << label << ":" << SourceStream::Indent
682 << statement << SourceStream::Unindent;
685 void ThrowNode::streamTo(SourceStream &s) const
687 s << SourceStream::Endl << "throw " << expr << ";";
690 void TryNode::streamTo(SourceStream &s) const
692 s << "try " << tryBlock;
694 s << SourceStream::Endl << "catch (" << exceptionIdent << ")" << catchBlock;
696 s << SourceStream::Endl << "finally " << finallyBlock;
699 void ParameterNode::streamTo(SourceStream &s) const
702 for (ParameterNode *n = next.get(); n; n = n->next.get())
706 void FuncDeclNode::streamTo(SourceStream &s) const
708 s << SourceStream::Endl << "function " << ident << "(" << param << ")" << body;
711 void FuncExprNode::streamTo(SourceStream &s) const
713 s << "function " << ident << "(" << param << ")" << body;
716 void SourceElementsNode::streamTo(SourceStream &s) const
718 for (const SourceElementsNode *n = this; n; n = n->next.get())