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

Last change on this file since 12512 was 12317, checked in by mjs, 19 years ago

Reviewed by Tim Hatcher.


  • it's "Franklin Street", not "Franklin Steet"
  • kjs/array_instance.h:
  • kjs/array_object.cpp:
  • kjs/array_object.h:
  • kjs/bool_object.cpp:
  • kjs/bool_object.h:
  • kjs/collector.cpp:
  • kjs/collector.h:
  • kjs/completion.h:
  • kjs/context.h:
  • kjs/date_object.cpp:
  • kjs/date_object.h:
  • kjs/debugger.cpp:
  • kjs/debugger.h:
  • kjs/dtoa.h:
  • kjs/error_object.cpp:
  • kjs/error_object.h:
  • kjs/function.cpp:
  • kjs/function.h:
  • kjs/function_object.cpp:
  • kjs/function_object.h:
  • kjs/grammar.y:
  • kjs/identifier.cpp:
  • kjs/identifier.h:
  • kjs/internal.cpp:
  • kjs/internal.h:
  • kjs/interpreter.cpp:
  • kjs/interpreter.h:
  • kjs/lexer.cpp:
  • kjs/lexer.h:
  • kjs/list.cpp:
  • kjs/list.h:
  • kjs/lookup.cpp:
  • kjs/lookup.h:
  • kjs/math_object.cpp:
  • kjs/math_object.h:
  • kjs/nodes.cpp:
  • kjs/nodes.h:
  • kjs/nodes2string.cpp:
  • kjs/number_object.cpp:
  • kjs/number_object.h:
  • kjs/object.cpp:
  • kjs/object.h:
  • kjs/object_object.cpp:
  • kjs/object_object.h:
  • kjs/operations.cpp:
  • kjs/operations.h:
  • kjs/property_map.cpp:
  • kjs/property_map.h:
  • kjs/property_slot.cpp:
  • kjs/property_slot.h:
  • kjs/reference.cpp:
  • kjs/reference.h:
  • kjs/reference_list.cpp:
  • kjs/reference_list.h:
  • kjs/regexp.cpp:
  • kjs/regexp.h:
  • kjs/regexp_object.cpp:
  • kjs/regexp_object.h:
  • kjs/scope_chain.cpp:
  • kjs/scope_chain.h:
  • kjs/simple_number.h:
  • kjs/string_object.cpp:
  • kjs/string_object.h:
  • kjs/testkjs.cpp:
  • kjs/types.h:
  • kjs/ustring.cpp:
  • kjs/ustring.h:
  • kjs/value.cpp:
  • kjs/value.h:
  • kxmlcore/AlwaysInline.h:
  • kxmlcore/ListRefPtr.h:
  • kxmlcore/PassRefPtr.h:
  • kxmlcore/RefPtr.h:
  • Property svn:eol-style set to native
File size: 14.4 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 Street, 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->next.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 PropertyListNode::streamTo(SourceStream &s) const
159{
160 s << node;
161
162 for (const PropertyListNode *n = next.get(); n; n = n->next.get())
163 s << ", " << n->node;
164}
165
166void PropertyNode::streamTo(SourceStream &s) const
167{
168 switch (type) {
169 case Constant:
170 s << name << ": " << assign;
171 break;
172 case Getter:
173 case Setter: {
174 const FuncExprNode *func = static_cast<const FuncExprNode *>(assign.get());
175 if (type == Getter)
176 s << "get ";
177 else
178 s << "set ";
179
180 s << name << "(" << func->param << ")" << func->body;
181 break;
182 }
183 }
184}
185
186void PropertyNameNode::streamTo(SourceStream &s) const
187{
188 if (str.isNull())
189 s << UString::from(numeric);
190 else
191 s << str;
192}
193
194void BracketAccessorNode::streamTo(SourceStream &s) const
195{
196 s << expr1 << "[" << expr2 << "]";
197}
198
199void DotAccessorNode::streamTo(SourceStream &s) const
200{
201 s << expr << "." << ident;
202}
203
204void ArgumentListNode::streamTo(SourceStream &s) const
205{
206 s << expr;
207 for (ArgumentListNode *n = next.get(); n; n = n->next.get())
208 s << ", " << n->expr;
209}
210
211void ArgumentsNode::streamTo(SourceStream &s) const
212{
213 s << "(" << list << ")";
214}
215
216void NewExprNode::streamTo(SourceStream &s) const
217{
218 s << "new " << expr << args;
219}
220
221void FunctionCallValueNode::streamTo(SourceStream &s) const
222{
223 s << expr << args;
224}
225
226void FunctionCallResolveNode::streamTo(SourceStream &s) const
227{
228 s << ident << args;
229}
230
231void FunctionCallBracketNode::streamTo(SourceStream &s) const
232{
233 s << base << "[" << subscript << "]" << args;
234}
235
236void FunctionCallParenBracketNode::streamTo(SourceStream &s) const
237{
238 s << "(" << base << "[" << subscript << "])" << args;
239}
240
241void FunctionCallDotNode::streamTo(SourceStream &s) const
242{
243 s << base << "." << ident << args;
244}
245
246void FunctionCallParenDotNode::streamTo(SourceStream &s) const
247{
248 s << "(" << base << "." << ident << ")" << args;
249}
250
251void PostfixResolveNode::streamTo(SourceStream &s) const
252{
253 s << m_ident;
254 if (m_oper == OpPlusPlus)
255 s << "++";
256 else
257 s << "--";
258}
259
260void PostfixBracketNode::streamTo(SourceStream &s) const
261{
262 s << m_base << "[" << m_subscript << "]";
263 if (m_oper == OpPlusPlus)
264 s << "++";
265 else
266 s << "--";
267}
268
269void PostfixDotNode::streamTo(SourceStream &s) const
270{
271 s << m_base << "." << m_ident;
272 if (m_oper == OpPlusPlus)
273 s << "++";
274 else
275 s << "--";
276}
277
278void DeleteResolveNode::streamTo(SourceStream &s) const
279{
280 s << "delete " << m_ident;
281}
282
283void DeleteBracketNode::streamTo(SourceStream &s) const
284{
285 s << "delete " << m_base << "[" << m_subscript << "]";
286}
287
288void DeleteDotNode::streamTo(SourceStream &s) const
289{
290 s << "delete " << m_base << "." << m_ident;
291}
292
293void DeleteValueNode::streamTo(SourceStream &s) const
294{
295 s << "delete " << m_expr;
296}
297
298void VoidNode::streamTo(SourceStream &s) const
299{
300 s << "void " << expr;
301}
302
303void TypeOfValueNode::streamTo(SourceStream &s) const
304{
305 s << "typeof " << m_expr;
306}
307
308void TypeOfResolveNode::streamTo(SourceStream &s) const
309{
310 s << "typeof " << m_ident;
311}
312
313void PrefixResolveNode::streamTo(SourceStream &s) const
314{
315 if (m_oper == OpPlusPlus)
316 s << "++";
317 else
318 s << "--";
319 s << m_ident;
320}
321
322void PrefixBracketNode::streamTo(SourceStream &s) const
323{
324 if (m_oper == OpPlusPlus)
325 s << "++";
326 else
327 s << "--";
328 s << m_base << "[" << m_subscript << "]";
329}
330
331void PrefixDotNode::streamTo(SourceStream &s) const
332{
333 if (m_oper == OpPlusPlus)
334 s << "++";
335 else
336 s << "--";
337 s << m_base << "." << m_ident;
338}
339
340void UnaryPlusNode::streamTo(SourceStream &s) const
341{
342 s << "+" << expr;
343}
344
345void NegateNode::streamTo(SourceStream &s) const
346{
347 s << "-" << expr;
348}
349
350void BitwiseNotNode::streamTo(SourceStream &s) const
351{
352 s << "~" << expr;
353}
354
355void LogicalNotNode::streamTo(SourceStream &s) const
356{
357 s << "!" << expr;
358}
359
360void MultNode::streamTo(SourceStream &s) const
361{
362 s << term1 << oper << term2;
363}
364
365void AddNode::streamTo(SourceStream &s) const
366{
367 s << term1 << oper << term2;
368}
369
370void ShiftNode::streamTo(SourceStream &s) const
371{
372 s << term1;
373 if (oper == OpLShift)
374 s << "<<";
375 else if (oper == OpRShift)
376 s << ">>";
377 else
378 s << ">>>";
379 s << term2;
380}
381
382void RelationalNode::streamTo(SourceStream &s) const
383{
384 s << expr1;
385 switch (oper) {
386 case OpLess:
387 s << " < ";
388 break;
389 case OpGreater:
390 s << " > ";
391 break;
392 case OpLessEq:
393 s << " <= ";
394 break;
395 case OpGreaterEq:
396 s << " >= ";
397 break;
398 case OpInstanceOf:
399 s << " instanceof ";
400 break;
401 case OpIn:
402 s << " in ";
403 break;
404 default:
405 ;
406 }
407 s << expr2;
408}
409
410void EqualNode::streamTo(SourceStream &s) const
411{
412 s << expr1;
413 switch (oper) {
414 case OpEqEq:
415 s << " == ";
416 break;
417 case OpNotEq:
418 s << " != ";
419 break;
420 case OpStrEq:
421 s << " === ";
422 break;
423 case OpStrNEq:
424 s << " !== ";
425 break;
426 default:
427 ;
428 }
429 s << expr2;
430}
431
432void BitOperNode::streamTo(SourceStream &s) const
433{
434 s << expr1;
435 if (oper == OpBitAnd)
436 s << " & ";
437 else if (oper == OpBitXOr)
438 s << " ^ ";
439 else
440 s << " | ";
441 s << expr2;
442}
443
444void BinaryLogicalNode::streamTo(SourceStream &s) const
445{
446 s << expr1 << (oper == OpAnd ? " && " : " || ") << expr2;
447}
448
449void ConditionalNode::streamTo(SourceStream &s) const
450{
451 s << logical << " ? " << expr1 << " : " << expr2;
452}
453
454static void streamAssignmentOperatorTo(SourceStream &s, Operator oper)
455{
456 const char *opStr;
457 switch (oper) {
458 case OpEqual:
459 opStr = " = ";
460 break;
461 case OpMultEq:
462 opStr = " *= ";
463 break;
464 case OpDivEq:
465 opStr = " /= ";
466 break;
467 case OpPlusEq:
468 opStr = " += ";
469 break;
470 case OpMinusEq:
471 opStr = " -= ";
472 break;
473 case OpLShift:
474 opStr = " <<= ";
475 break;
476 case OpRShift:
477 opStr = " >>= ";
478 break;
479 case OpURShift:
480 opStr = " >>>= ";
481 break;
482 case OpAndEq:
483 opStr = " &= ";
484 break;
485 case OpXOrEq:
486 opStr = " ^= ";
487 break;
488 case OpOrEq:
489 opStr = " |= ";
490 break;
491 case OpModEq:
492 opStr = " %= ";
493 break;
494 default:
495 opStr = " ?= ";
496 }
497 s << opStr;
498}
499
500void AssignResolveNode::streamTo(SourceStream &s) const
501{
502 s << m_ident;
503 streamAssignmentOperatorTo(s, m_oper);
504 s << m_right;
505}
506
507void AssignBracketNode::streamTo(SourceStream &s) const
508{
509 s << m_base << "[" << m_subscript << "]";
510 streamAssignmentOperatorTo(s, m_oper);
511 s << m_right;
512}
513
514void AssignDotNode::streamTo(SourceStream &s) const
515{
516 s << m_base << "." << m_ident;
517 streamAssignmentOperatorTo(s, m_oper);
518 s << m_right;
519}
520
521void CommaNode::streamTo(SourceStream &s) const
522{
523 s << expr1 << ", " << expr2;
524}
525
526void StatListNode::streamTo(SourceStream &s) const
527{
528 for (const StatListNode *n = this; n; n = n->next.get())
529 s << n->statement;
530}
531
532void AssignExprNode::streamTo(SourceStream &s) const
533{
534 s << " = " << expr;
535}
536
537void VarDeclNode::streamTo(SourceStream &s) const
538{
539 s << ident << init;
540}
541
542void VarDeclListNode::streamTo(SourceStream &s) const
543{
544 s << var;
545 for (VarDeclListNode *n = next.get(); n; n = n->next.get())
546 s << ", " << n->var;
547}
548
549void VarStatementNode::streamTo(SourceStream &s) const
550{
551 s << SourceStream::Endl << "var " << next << ";";
552}
553
554void BlockNode::streamTo(SourceStream &s) const
555{
556 s << SourceStream::Endl << "{" << SourceStream::Indent
557 << source << SourceStream::Unindent << SourceStream::Endl << "}";
558}
559
560void EmptyStatementNode::streamTo(SourceStream &s) const
561{
562 s << SourceStream::Endl << ";";
563}
564
565void ExprStatementNode::streamTo(SourceStream &s) const
566{
567 s << SourceStream::Endl << expr << ";";
568}
569
570void IfNode::streamTo(SourceStream &s) const
571{
572 s << SourceStream::Endl << "if (" << expr << ")" << SourceStream::Indent
573 << statement1 << SourceStream::Unindent;
574 if (statement2)
575 s << SourceStream::Endl << "else" << SourceStream::Indent
576 << statement2 << SourceStream::Unindent;
577}
578
579void DoWhileNode::streamTo(SourceStream &s) const
580{
581 s << SourceStream::Endl << "do " << SourceStream::Indent
582 << statement << SourceStream::Unindent << SourceStream::Endl
583 << "while (" << expr << ");";
584}
585
586void WhileNode::streamTo(SourceStream &s) const
587{
588 s << SourceStream::Endl << "while (" << expr << ")" << SourceStream::Indent
589 << statement << SourceStream::Unindent;
590}
591
592void ForNode::streamTo(SourceStream &s) const
593{
594 s << SourceStream::Endl << "for ("
595 << expr1 // TODO: doesn't properly do "var i = 0"
596 << "; " << expr2
597 << "; " << expr3
598 << ")" << SourceStream::Indent << statement << SourceStream::Unindent;
599}
600
601void ForInNode::streamTo(SourceStream &s) const
602{
603 s << SourceStream::Endl << "for (";
604 if (varDecl)
605 s << "var " << varDecl;
606 else
607 s << lexpr;
608
609 if (init)
610 s << " = " << init;
611 s << " in " << expr << ")" << SourceStream::Indent
612 << statement << SourceStream::Unindent;
613}
614
615void ContinueNode::streamTo(SourceStream &s) const
616{
617 s << SourceStream::Endl << "continue";
618 if (!ident.isNull())
619 s << " " << ident;
620 s << ";";
621}
622
623void BreakNode::streamTo(SourceStream &s) const
624{
625 s << SourceStream::Endl << "break";
626 if (!ident.isNull())
627 s << " " << ident;
628 s << ";";
629}
630
631void ReturnNode::streamTo(SourceStream &s) const
632{
633 s << SourceStream::Endl << "return";
634 if (value)
635 s << " " << value;
636 s << ";";
637}
638
639void WithNode::streamTo(SourceStream &s) const
640{
641 s << SourceStream::Endl << "with (" << expr << ") "
642 << statement;
643}
644
645void CaseClauseNode::streamTo(SourceStream &s) const
646{
647 s << SourceStream::Endl;
648 if (expr)
649 s << "case " << expr;
650 else
651 s << "default";
652 s << ":" << SourceStream::Indent;
653 if (next)
654 s << next;
655 s << SourceStream::Unindent;
656}
657
658void ClauseListNode::streamTo(SourceStream &s) const
659{
660 for (const ClauseListNode *n = this; n; n = n->getNext())
661 s << n->getClause();
662}
663
664void CaseBlockNode::streamTo(SourceStream &s) const
665{
666 for (const ClauseListNode *n = list1.get(); n; n = n->getNext())
667 s << n->getClause();
668 if (def)
669 s << def;
670 for (const ClauseListNode *n = list2.get(); n; n = n->getNext())
671 s << n->getClause();
672}
673
674void SwitchNode::streamTo(SourceStream &s) const
675{
676 s << SourceStream::Endl << "switch (" << expr << ") {"
677 << SourceStream::Indent << block << SourceStream::Unindent
678 << SourceStream::Endl << "}";
679}
680
681void LabelNode::streamTo(SourceStream &s) const
682{
683 s << SourceStream::Endl << label << ":" << SourceStream::Indent
684 << statement << SourceStream::Unindent;
685}
686
687void ThrowNode::streamTo(SourceStream &s) const
688{
689 s << SourceStream::Endl << "throw " << expr << ";";
690}
691
692void TryNode::streamTo(SourceStream &s) const
693{
694 s << "try " << tryBlock;
695 if (catchBlock)
696 s << SourceStream::Endl << "catch (" << exceptionIdent << ")" << catchBlock;
697 if (finallyBlock)
698 s << SourceStream::Endl << "finally " << finallyBlock;
699}
700
701void ParameterNode::streamTo(SourceStream &s) const
702{
703 s << id;
704 for (ParameterNode *n = next.get(); n; n = n->next.get())
705 s << ", " << n->id;
706}
707
708void FuncDeclNode::streamTo(SourceStream &s) const
709{
710 s << "function " << ident << "(" << param << ")" << body;
711}
712
713void FuncExprNode::streamTo(SourceStream &s) const
714{
715 s << "function " << ident << "(" << param << ")" << body;
716}
717
718void SourceElementsNode::streamTo(SourceStream &s) const
719{
720 for (const SourceElementsNode *n = this; n; n = n->next.get())
721 s << n->node;
722}
Note: See TracBrowser for help on using the repository browser.