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

Last change on this file since 11377 was 11377, checked in by andersca, 19 years ago

2005-12-01 Anders Carlsson <[email protected]>

Reviewed by Darin.

Patch by Mark Rowe.

  • kjs/nodes2string.cpp: (ForInNode::streamTo): Add lexpr if there's no varDecl.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.0 KB
Line 
1/*
2 * This file is part of the KDE libraries
3 * Copyright (C) 2002 Harri Porten ([email protected])
4 * Copyright (C) 2003 Apple Computer, Inc.
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 Steet, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#include "config.h"
24#include "nodes.h"
25
26namespace KJS {
27 /**
28 * A simple text streaming class that helps with code indentation.
29 */
30 class SourceStream {
31 public:
32 enum Format {
33 Endl, Indent, Unindent
34 };
35
36 UString toString() const { return str; }
37 SourceStream& operator<<(const Identifier &);
38 SourceStream& operator<<(const UString &);
39 SourceStream& operator<<(const char *);
40 SourceStream& operator<<(char);
41 SourceStream& operator<<(Format f);
42 SourceStream& operator<<(const Node *);
43 template <typename T> SourceStream& operator<<(RefPtr<T> n) { return this->operator<<(n.get()); }
44 private:
45 UString str; /* TODO: buffer */
46 UString ind;
47 };
48};
49
50using namespace KJS;
51
52SourceStream& SourceStream::operator<<(char c)
53{
54 str += UString(c);
55 return *this;
56}
57
58SourceStream& SourceStream::operator<<(const char *s)
59{
60 str += UString(s);
61 return *this;
62}
63
64SourceStream& SourceStream::operator<<(const UString &s)
65{
66 str += s;
67 return *this;
68}
69
70SourceStream& SourceStream::operator<<(const Identifier &s)
71{
72 str += s.ustring();
73 return *this;
74}
75
76SourceStream& SourceStream::operator<<(const Node *n)
77{
78 if (n)
79 n->streamTo(*this);
80 return *this;
81}
82
83SourceStream& SourceStream::operator<<(Format f)
84{
85 switch (f) {
86 case Endl:
87 str += "\n" + ind;
88 break;
89 case Indent:
90 ind += " ";
91 break;
92 case Unindent:
93 ind = ind.substr(0, ind.size() - 2);
94 break;
95 }
96
97 return *this;
98}
99
100UString Node::toString() const
101{
102 SourceStream str;
103 streamTo(str);
104
105 return str.toString();
106}
107
108void NullNode::streamTo(SourceStream &s) const { s << "null"; }
109
110void BooleanNode::streamTo(SourceStream &s) const
111{
112 s << (value ? "true" : "false");
113}
114
115void NumberNode::streamTo(SourceStream &s) const { s << UString::from(value); }
116
117void StringNode::streamTo(SourceStream &s) const
118{
119 s << '"' << value << '"';
120}
121
122void RegExpNode::streamTo(SourceStream &s) const { s << pattern; }
123
124void ThisNode::streamTo(SourceStream &s) const { s << "this"; }
125
126void ResolveNode::streamTo(SourceStream &s) const { s << ident; }
127
128void GroupNode::streamTo(SourceStream &s) const
129{
130 s << "(" << group << ")";
131}
132
133void ElementNode::streamTo(SourceStream &s) const
134{
135 for (const ElementNode *n = this; n; n = n->list.get()) {
136 for (int i = 0; i < n->elision; i++)
137 s << ",";
138 s << n->node;
139 }
140}
141
142void ArrayNode::streamTo(SourceStream &s) const
143{
144 s << "[" << element;
145 for (int i = 0; i < elision; i++)
146 s << ",";
147 s << "]";
148}
149
150void ObjectLiteralNode::streamTo(SourceStream &s) const
151{
152 if (list)
153 s << "{ " << list << " }";
154 else
155 s << "{ }";
156}
157
158void PropertyValueNode::streamTo(SourceStream &s) const
159{
160 for (const PropertyValueNode *n = this; n; n = n->list.get())
161 s << n->name << ": " << n->assign;
162}
163
164void PropertyNode::streamTo(SourceStream &s) const
165{
166 if (str.isNull())
167 s << UString::from(numeric);
168 else
169 s << str;
170}
171
172void BracketAccessorNode::streamTo(SourceStream &s) const
173{
174 s << expr1 << "[" << expr2 << "]";
175}
176
177void DotAccessorNode::streamTo(SourceStream &s) const
178{
179 s << expr << "." << ident;
180}
181
182void ArgumentListNode::streamTo(SourceStream &s) const
183{
184 s << expr;
185 for (ArgumentListNode *n = list.get(); n; n = n->list.get())
186 s << ", " << n->expr;
187}
188
189void ArgumentsNode::streamTo(SourceStream &s) const
190{
191 s << "(" << list << ")";
192}
193
194void NewExprNode::streamTo(SourceStream &s) const
195{
196 s << "new " << expr << args;
197}
198
199void FunctionCallValueNode::streamTo(SourceStream &s) const
200{
201 s << expr << args;
202}
203
204void FunctionCallResolveNode::streamTo(SourceStream &s) const
205{
206 s << ident << args;
207}
208
209void FunctionCallBracketNode::streamTo(SourceStream &s) const
210{
211 s << base << "[" << subscript << "]" << args;
212}
213
214void FunctionCallParenBracketNode::streamTo(SourceStream &s) const
215{
216 s << "(" << base << "[" << subscript << "])" << args;
217}
218
219void FunctionCallDotNode::streamTo(SourceStream &s) const
220{
221 s << base << "." << ident << args;
222}
223
224void FunctionCallParenDotNode::streamTo(SourceStream &s) const
225{
226 s << "(" << base << "." << ident << ")" << args;
227}
228
229void PostfixResolveNode::streamTo(SourceStream &s) const
230{
231 s << m_ident;
232 if (m_oper == OpPlusPlus)
233 s << "++";
234 else
235 s << "--";
236}
237
238void PostfixBracketNode::streamTo(SourceStream &s) const
239{
240 s << m_base << "[" << m_subscript << "]";
241 if (m_oper == OpPlusPlus)
242 s << "++";
243 else
244 s << "--";
245}
246
247void PostfixDotNode::streamTo(SourceStream &s) const
248{
249 s << m_base << "." << m_ident;
250 if (m_oper == OpPlusPlus)
251 s << "++";
252 else
253 s << "--";
254}
255
256void DeleteResolveNode::streamTo(SourceStream &s) const
257{
258 s << "delete " << m_ident;
259}
260
261void DeleteBracketNode::streamTo(SourceStream &s) const
262{
263 s << "delete " << m_base << "[" << m_subscript << "]";
264}
265
266void DeleteDotNode::streamTo(SourceStream &s) const
267{
268 s << "delete " << m_base << "." << m_ident;
269}
270
271void DeleteValueNode::streamTo(SourceStream &s) const
272{
273 s << "delete " << m_expr;
274}
275
276void VoidNode::streamTo(SourceStream &s) const
277{
278 s << "void " << expr;
279}
280
281void TypeOfValueNode::streamTo(SourceStream &s) const
282{
283 s << "typeof " << m_expr;
284}
285
286void TypeOfResolveNode::streamTo(SourceStream &s) const
287{
288 s << "typeof " << m_ident;
289}
290
291void PrefixResolveNode::streamTo(SourceStream &s) const
292{
293 if (m_oper == OpPlusPlus)
294 s << "++";
295 else
296 s << "--";
297 s << m_ident;
298}
299
300void PrefixBracketNode::streamTo(SourceStream &s) const
301{
302 if (m_oper == OpPlusPlus)
303 s << "++";
304 else
305 s << "--";
306 s << m_base << "[" << m_subscript << "]";
307}
308
309void PrefixDotNode::streamTo(SourceStream &s) const
310{
311 if (m_oper == OpPlusPlus)
312 s << "++";
313 else
314 s << "--";
315 s << m_base << "." << m_ident;
316}
317
318void UnaryPlusNode::streamTo(SourceStream &s) const
319{
320 s << "+" << expr;
321}
322
323void NegateNode::streamTo(SourceStream &s) const
324{
325 s << "-" << expr;
326}
327
328void BitwiseNotNode::streamTo(SourceStream &s) const
329{
330 s << "~" << expr;
331}
332
333void LogicalNotNode::streamTo(SourceStream &s) const
334{
335 s << "!" << expr;
336}
337
338void MultNode::streamTo(SourceStream &s) const
339{
340 s << term1 << oper << term2;
341}
342
343void AddNode::streamTo(SourceStream &s) const
344{
345 s << term1 << oper << term2;
346}
347
348void ShiftNode::streamTo(SourceStream &s) const
349{
350 s << term1;
351 if (oper == OpLShift)
352 s << "<<";
353 else if (oper == OpRShift)
354 s << ">>";
355 else
356 s << ">>>";
357 s << term2;
358}
359
360void RelationalNode::streamTo(SourceStream &s) const
361{
362 s << expr1;
363 switch (oper) {
364 case OpLess:
365 s << " < ";
366 break;
367 case OpGreater:
368 s << " > ";
369 break;
370 case OpLessEq:
371 s << " <= ";
372 break;
373 case OpGreaterEq:
374 s << " >= ";
375 break;
376 case OpInstanceOf:
377 s << " instanceof ";
378 break;
379 case OpIn:
380 s << " in ";
381 break;
382 default:
383 ;
384 }
385 s << expr2;
386}
387
388void EqualNode::streamTo(SourceStream &s) const
389{
390 s << expr1;
391 switch (oper) {
392 case OpEqEq:
393 s << " == ";
394 break;
395 case OpNotEq:
396 s << " != ";
397 break;
398 case OpStrEq:
399 s << " === ";
400 break;
401 case OpStrNEq:
402 s << " !== ";
403 break;
404 default:
405 ;
406 }
407 s << expr2;
408}
409
410void BitOperNode::streamTo(SourceStream &s) const
411{
412 s << expr1;
413 if (oper == OpBitAnd)
414 s << " & ";
415 else if (oper == OpBitXOr)
416 s << " ^ ";
417 else
418 s << " | ";
419 s << expr2;
420}
421
422void BinaryLogicalNode::streamTo(SourceStream &s) const
423{
424 s << expr1 << (oper == OpAnd ? " && " : " || ") << expr2;
425}
426
427void ConditionalNode::streamTo(SourceStream &s) const
428{
429 s << logical << " ? " << expr1 << " : " << expr2;
430}
431
432static void streamAssignmentOperatorTo(SourceStream &s, Operator oper)
433{
434 const char *opStr;
435 switch (oper) {
436 case OpEqual:
437 opStr = " = ";
438 break;
439 case OpMultEq:
440 opStr = " *= ";
441 break;
442 case OpDivEq:
443 opStr = " /= ";
444 break;
445 case OpPlusEq:
446 opStr = " += ";
447 break;
448 case OpMinusEq:
449 opStr = " -= ";
450 break;
451 case OpLShift:
452 opStr = " <<= ";
453 break;
454 case OpRShift:
455 opStr = " >>= ";
456 break;
457 case OpURShift:
458 opStr = " >>>= ";
459 break;
460 case OpAndEq:
461 opStr = " &= ";
462 break;
463 case OpXOrEq:
464 opStr = " ^= ";
465 break;
466 case OpOrEq:
467 opStr = " |= ";
468 break;
469 case OpModEq:
470 opStr = " %= ";
471 break;
472 default:
473 opStr = " ?= ";
474 }
475 s << opStr;
476}
477
478void AssignResolveNode::streamTo(SourceStream &s) const
479{
480 s << m_ident;
481 streamAssignmentOperatorTo(s, m_oper);
482 s << m_right;
483}
484
485void AssignBracketNode::streamTo(SourceStream &s) const
486{
487 s << m_base << "[" << m_subscript << "]";
488 streamAssignmentOperatorTo(s, m_oper);
489 s << m_right;
490}
491
492void AssignDotNode::streamTo(SourceStream &s) const
493{
494 s << m_base << "." << m_ident;
495 streamAssignmentOperatorTo(s, m_oper);
496 s << m_right;
497}
498
499void CommaNode::streamTo(SourceStream &s) const
500{
501 s << expr1 << ", " << expr2;
502}
503
504void StatListNode::streamTo(SourceStream &s) const
505{
506 for (const StatListNode *n = this; n; n = n->list.get())
507 s << n->statement;
508}
509
510void AssignExprNode::streamTo(SourceStream &s) const
511{
512 s << " = " << expr;
513}
514
515void VarDeclNode::streamTo(SourceStream &s) const
516{
517 s << ident << init;
518}
519
520void VarDeclListNode::streamTo(SourceStream &s) const
521{
522 s << var;
523 for (VarDeclListNode *n = list.get(); n; n = n->list.get())
524 s << ", " << n->var;
525}
526
527void VarStatementNode::streamTo(SourceStream &s) const
528{
529 s << SourceStream::Endl << "var " << list << ";";
530}
531
532void BlockNode::streamTo(SourceStream &s) const
533{
534 s << SourceStream::Endl << "{" << SourceStream::Indent
535 << source << SourceStream::Unindent << SourceStream::Endl << "}";
536}
537
538void EmptyStatementNode::streamTo(SourceStream &s) const
539{
540 s << SourceStream::Endl << ";";
541}
542
543void ExprStatementNode::streamTo(SourceStream &s) const
544{
545 s << SourceStream::Endl << expr << ";";
546}
547
548void IfNode::streamTo(SourceStream &s) const
549{
550 s << SourceStream::Endl << "if (" << expr << ")" << SourceStream::Indent
551 << statement1 << SourceStream::Unindent;
552 if (statement2)
553 s << SourceStream::Endl << "else" << SourceStream::Indent
554 << statement2 << SourceStream::Unindent;
555}
556
557void DoWhileNode::streamTo(SourceStream &s) const
558{
559 s << SourceStream::Endl << "do " << SourceStream::Indent
560 << statement << SourceStream::Unindent << SourceStream::Endl
561 << "while (" << expr << ");";
562}
563
564void WhileNode::streamTo(SourceStream &s) const
565{
566 s << SourceStream::Endl << "while (" << expr << ")" << SourceStream::Indent
567 << statement << SourceStream::Unindent;
568}
569
570void ForNode::streamTo(SourceStream &s) const
571{
572 s << SourceStream::Endl << "for ("
573 << expr1 // TODO: doesn't properly do "var i = 0"
574 << "; " << expr2
575 << "; " << expr3
576 << ")" << SourceStream::Indent << statement << SourceStream::Unindent;
577}
578
579void ForInNode::streamTo(SourceStream &s) const
580{
581 s << SourceStream::Endl << "for (";
582 if (varDecl)
583 s << "var " << varDecl;
584 else
585 s << lexpr;
586
587 if (init)
588 s << " = " << init;
589 s << " in " << expr << ")" << SourceStream::Indent
590 << statement << SourceStream::Unindent;
591}
592
593void ContinueNode::streamTo(SourceStream &s) const
594{
595 s << SourceStream::Endl << "continue";
596 if (!ident.isNull())
597 s << " " << ident;
598 s << ";";
599}
600
601void BreakNode::streamTo(SourceStream &s) const
602{
603 s << SourceStream::Endl << "break";
604 if (!ident.isNull())
605 s << " " << ident;
606 s << ";";
607}
608
609void ReturnNode::streamTo(SourceStream &s) const
610{
611 s << SourceStream::Endl << "return";
612 if (value)
613 s << " " << value;
614 s << ";";
615}
616
617void WithNode::streamTo(SourceStream &s) const
618{
619 s << SourceStream::Endl << "with (" << expr << ") "
620 << statement;
621}
622
623void CaseClauseNode::streamTo(SourceStream &s) const
624{
625 s << SourceStream::Endl;
626 if (expr)
627 s << "case " << expr;
628 else
629 s << "default";
630 s << ":" << SourceStream::Indent;
631 if (list)
632 s << list;
633 s << SourceStream::Unindent;
634}
635
636void ClauseListNode::streamTo(SourceStream &s) const
637{
638 for (const ClauseListNode *n = this; n; n = n->next())
639 s << n->clause();
640}
641
642void CaseBlockNode::streamTo(SourceStream &s) const
643{
644 for (const ClauseListNode *n = list1.get(); n; n = n->next())
645 s << n->clause();
646 if (def)
647 s << def;
648 for (const ClauseListNode *n = list2.get(); n; n = n->next())
649 s << n->clause();
650}
651
652void SwitchNode::streamTo(SourceStream &s) const
653{
654 s << SourceStream::Endl << "switch (" << expr << ") {"
655 << SourceStream::Indent << block << SourceStream::Unindent
656 << SourceStream::Endl << "}";
657}
658
659void LabelNode::streamTo(SourceStream &s) const
660{
661 s << SourceStream::Endl << label << ":" << SourceStream::Indent
662 << statement << SourceStream::Unindent;
663}
664
665void ThrowNode::streamTo(SourceStream &s) const
666{
667 s << SourceStream::Endl << "throw " << expr << ";";
668}
669
670void TryNode::streamTo(SourceStream &s) const
671{
672 s << "try " << tryBlock;
673 if (catchBlock)
674 s << SourceStream::Endl << "catch (" << exceptionIdent << ")" << catchBlock;
675 if (finallyBlock)
676 s << SourceStream::Endl << "finally " << finallyBlock;
677}
678
679void ParameterNode::streamTo(SourceStream &s) const
680{
681 s << id;
682 for (ParameterNode *n = next.get(); n; n = n->next.get())
683 s << ", " << n->id;
684}
685
686void FuncDeclNode::streamTo(SourceStream &s) const
687{
688 s << "function " << ident << "(" << param << ")" << body;
689}
690
691void FuncExprNode::streamTo(SourceStream &s) const
692{
693 s << "function " << ident << "(" << param << ")" << body;
694}
695
696void SourceElementsNode::streamTo(SourceStream &s) const
697{
698 for (const SourceElementsNode *n = this; n; n = n->elements.get())
699 s << n->element;
700}
Note: See TracBrowser for help on using the repository browser.