diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | ce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch) | |
tree | 5ac38a06f3dde268dc7927dc155896926aaf7012 /kjs/nodes2string.cpp | |
download | tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kjs/nodes2string.cpp')
-rw-r--r-- | kjs/nodes2string.cpp | 629 |
1 files changed, 629 insertions, 0 deletions
diff --git a/kjs/nodes2string.cpp b/kjs/nodes2string.cpp new file mode 100644 index 000000000..25ec0d712 --- /dev/null +++ b/kjs/nodes2string.cpp @@ -0,0 +1,629 @@ +// -*- c-basic-offset: 2 -*- +/* + * This file is part of the KDE libraries + * Copyright (C) 2002 Harri Porten (porten@kde.org) + * Copyright (C) 2003 Apple Computer, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "nodes.h" + +namespace KJS { + /** + * A simple text streaming class that helps with code indentation. + */ + class SourceStream { + public: + enum Format { + Endl, Indent, Unindent + }; + + UString toString() const { return str; } + SourceStream& operator<<(const Identifier &); + SourceStream& operator<<(const KJS::UString &); + SourceStream& operator<<(const char *); + SourceStream& operator<<(char); + SourceStream& operator<<(Format f); + SourceStream& operator<<(const Node *); + private: + UString str; /* TODO: buffer */ + UString ind; + }; +} + +using namespace KJS; + +SourceStream& SourceStream::operator<<(char c) +{ + str += UString(c); + return *this; +} + +SourceStream& SourceStream::operator<<(const char *s) +{ + str += UString(s); + return *this; +} + +SourceStream& SourceStream::operator<<(const UString &s) +{ + str += s; + return *this; +} + +SourceStream& SourceStream::operator<<(const Identifier &s) +{ + str += s.ustring(); + return *this; +} + +SourceStream& SourceStream::operator<<(const Node *n) +{ + if (n) + n->streamTo(*this); + return *this; +} + +SourceStream& SourceStream::operator<<(Format f) +{ + switch (f) { + case Endl: + str += "\n" + ind; + break; + case Indent: + ind += " "; + break; + case Unindent: + ind = ind.substr(0, ind.size() - 2); + break; + } + + return *this; +} + +UString unescapeStr(UString str) +{ + UString unescaped = ""; + int i = 0; + int copied = 0; + for (i = 0; i <= str.size(); i++) { + if (str[i] == '"') { + if (copied < i) + unescaped += str.substr(copied,i-copied); + copied = i+1; + unescaped += "\\\""; + } + } + if (copied < i) + unescaped += str.substr(copied,i-copied); + return unescaped; +} + +UString Node::toCode() const +{ + SourceStream str; + streamTo(str); + + return str.toString(); +} + +void NullNode::streamTo(SourceStream &s) const { s << "null"; } + +void BooleanNode::streamTo(SourceStream &s) const +{ + s << (val ? "true" : "false"); +} + +void NumberNode::streamTo(SourceStream &s) const { s << UString::from(val); } + +void StringNode::streamTo(SourceStream &s) const +{ + s << '"' << unescapeStr(val) << '"'; +} + +void RegExpNode::streamTo(SourceStream &s) const { s << "/" << pattern << "/" << flags; } + +void ThisNode::streamTo(SourceStream &s) const { s << "this"; } + +void ResolveNode::streamTo(SourceStream &s) const { s << ident; } + +void GroupNode::streamTo(SourceStream &s) const +{ + s << "(" << group << ")"; +} + +void ElementNode::streamTo(SourceStream &s) const +{ + for (const ElementNode *n = this; n; n = n->list) { + for (int i = 0; i < n->elision; i++) + s << ","; + s << n->node; + if ( n->list ) + s << ","; + } +} + +void ArrayNode::streamTo(SourceStream &s) const +{ + s << "[" << element; + for (int i = 0; i < elision; i++) + s << ","; + s << "]"; +} + +void ObjectLiteralNode::streamTo(SourceStream &s) const +{ + if (list) + s << "{ " << list << " }"; + else + s << "{ }"; +} + +void PropertyValueNode::streamTo(SourceStream &s) const +{ + for (const PropertyValueNode *n = this; n; n = n->list) + s << n->name << ": " << n->assign; +} + +void PropertyNode::streamTo(SourceStream &s) const +{ + if (str.isNull()) + s << UString::from(numeric); + else + s << str; +} + +void AccessorNode1::streamTo(SourceStream &s) const +{ + s << expr1 << "[" << expr2 << "]"; +} + +void AccessorNode2::streamTo(SourceStream &s) const +{ + s << expr << "." << ident; +} + +void ArgumentListNode::streamTo(SourceStream &s) const +{ + s << expr; + for (ArgumentListNode *n = list; n; n = n->list) + s << ", " << n->expr; +} + +void ArgumentsNode::streamTo(SourceStream &s) const +{ + s << "(" << list << ")"; +} + +void NewExprNode::streamTo(SourceStream &s) const +{ + s << "new " << expr << args; +} + +void FunctionCallNode::streamTo(SourceStream &s) const +{ + s << expr << args; +} + +void PostfixNode::streamTo(SourceStream &s) const +{ + s << expr; + if (oper == OpPlusPlus) + s << "++"; + else + s << "--"; +} + +void DeleteNode::streamTo(SourceStream &s) const +{ + s << "delete " << expr; +} + +void VoidNode::streamTo(SourceStream &s) const +{ + s << "void " << expr; +} + +void TypeOfNode::streamTo(SourceStream &s) const +{ + s << "typeof " << expr; +} + +void PrefixNode::streamTo(SourceStream &s) const +{ + s << (oper == OpPlusPlus ? "++" : "--") << expr; +} + +void UnaryPlusNode::streamTo(SourceStream &s) const +{ + s << "+" << expr; +} + +void NegateNode::streamTo(SourceStream &s) const +{ + s << "-" << expr; +} + +void BitwiseNotNode::streamTo(SourceStream &s) const +{ + s << "~" << expr; +} + +void LogicalNotNode::streamTo(SourceStream &s) const +{ + s << "!" << expr; +} + +void MultNode::streamTo(SourceStream &s) const +{ + s << term1 << oper << term2; +} + +void AddNode::streamTo(SourceStream &s) const +{ + s << term1 << oper << term2; +} + +void AppendStringNode::streamTo(SourceStream &s) const +{ + s << term << "+" << '"' << unescapeStr(str) << '"'; +} + +void ShiftNode::streamTo(SourceStream &s) const +{ + s << term1; + if (oper == OpLShift) + s << "<<"; + else if (oper == OpRShift) + s << ">>"; + else + s << ">>>"; + s << term2; +} + +void RelationalNode::streamTo(SourceStream &s) const +{ + s << expr1; + switch (oper) { + case OpLess: + s << " < "; + break; + case OpGreater: + s << " > "; + break; + case OpLessEq: + s << " <= "; + break; + case OpGreaterEq: + s << " >= "; + break; + case OpInstanceOf: + s << " instanceof "; + break; + case OpIn: + s << " in "; + break; + default: + ; + } + s << expr2; +} + +void EqualNode::streamTo(SourceStream &s) const +{ + s << expr1; + switch (oper) { + case OpEqEq: + s << " == "; + break; + case OpNotEq: + s << " != "; + break; + case OpStrEq: + s << " === "; + break; + case OpStrNEq: + s << " !== "; + break; + default: + ; + } + s << expr2; +} + +void BitOperNode::streamTo(SourceStream &s) const +{ + s << expr1; + if (oper == OpBitAnd) + s << " & "; + else if (oper == OpBitXOr) + s << " ^ "; + else + s << " | "; + s << expr2; +} + +void BinaryLogicalNode::streamTo(SourceStream &s) const +{ + s << expr1 << (oper == OpAnd ? " && " : " || ") << expr2; +} + +void ConditionalNode::streamTo(SourceStream &s) const +{ + s << logical << " ? " << expr1 << " : " << expr2; +} + +void AssignNode::streamTo(SourceStream &s) const +{ + s << left; + const char *opStr; + switch (oper) { + case OpEqual: + opStr = " = "; + break; + case OpMultEq: + opStr = " *= "; + break; + case OpDivEq: + opStr = " /= "; + break; + case OpPlusEq: + opStr = " += "; + break; + case OpMinusEq: + opStr = " -= "; + break; + case OpLShift: + opStr = " <<= "; + break; + case OpRShift: + opStr = " >>= "; + break; + case OpURShift: + opStr = " >>= "; + break; + case OpAndEq: + opStr = " &= "; + break; + case OpXOrEq: + opStr = " ^= "; + break; + case OpOrEq: + opStr = " |= "; + break; + case OpModEq: + opStr = " %= "; + break; + default: + opStr = " ?= "; + } + s << opStr << expr; +} + +void CommaNode::streamTo(SourceStream &s) const +{ + s << expr1 << ", " << expr2; +} + +void StatListNode::streamTo(SourceStream &s) const +{ + for (const StatListNode *n = this; n; n = n->list) + s << n->statement; +} + +void AssignExprNode::streamTo(SourceStream &s) const +{ + s << " = " << expr; +} + +void VarDeclNode::streamTo(SourceStream &s) const +{ + s << ident << init; +} + +void VarDeclListNode::streamTo(SourceStream &s) const +{ + s << var; + for (VarDeclListNode *n = list; n; n = n->list) + s << ", " << n->var; +} + +void VarStatementNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "var " << list << ";"; +} + +void BlockNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "{" << SourceStream::Indent + << source << SourceStream::Unindent << SourceStream::Endl << "}"; +} + +void EmptyStatementNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << ";"; +} + +void ExprStatementNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << expr << ";"; +} + +void IfNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "if (" << expr << ")" << SourceStream::Indent + << statement1 << SourceStream::Unindent; + if (statement2) + s << SourceStream::Endl << "else" << SourceStream::Indent + << statement2 << SourceStream::Unindent; +} + +void DoWhileNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "do " << SourceStream::Indent + << statement << SourceStream::Unindent << SourceStream::Endl + << "while (" << expr << ");"; +} + +void WhileNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "while (" << expr << ")" << SourceStream::Indent + << statement << SourceStream::Unindent; +} + +void ForNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "for (" + << expr1 // TODO: doesn't properly do "var i = 0" + << "; " << expr2 + << "; " << expr3 + << ")" << SourceStream::Indent << statement << SourceStream::Unindent; +} + +void ForInNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "for ("; + if (varDecl) + s << "var " << varDecl; + if (init) + s << " = " << init; + s << " in " << expr << ")" << SourceStream::Indent + << statement << SourceStream::Unindent; +} + +void ContinueNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "continue"; + if (!ident.isNull()) + s << " " << ident; + s << ";"; +} + +void BreakNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "break"; + if (!ident.isNull()) + s << " " << ident; + s << ";"; +} + +void ReturnNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "return"; + if (value) + s << " " << value; + s << ";"; +} + +void WithNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "with (" << expr << ") " + << statement; +} + +void CaseClauseNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl; + if (expr) + s << "case " << expr; + else + s << "default"; + s << ":" << SourceStream::Indent; + if (list) + s << list; + s << SourceStream::Unindent; +} + +void ClauseListNode::streamTo(SourceStream &s) const +{ + for (const ClauseListNode *n = this; n; n = n->next()) + s << n->clause(); +} + +void CaseBlockNode::streamTo(SourceStream &s) const +{ + for (const ClauseListNode *n = list1; n; n = n->next()) + s << n->clause(); + if (def) + s << def; + for (const ClauseListNode *n = list2; n; n = n->next()) + s << n->clause(); +} + +void SwitchNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "switch (" << expr << ") {" + << SourceStream::Indent << block << SourceStream::Unindent + << SourceStream::Endl << "}"; +} + +void LabelNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << label << ":" << SourceStream::Indent + << statement << SourceStream::Unindent; +} + +void ThrowNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "throw " << expr << ";"; +} + +void CatchNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "catch (" << ident << ")" << block; +} + +void FinallyNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "finally " << block; +} + +void TryNode::streamTo(SourceStream &s) const +{ + s << SourceStream::Endl << "try " << block + << _catch + << _final; +} + +void ParameterNode::streamTo(SourceStream &s) const +{ + s << id; + for (ParameterNode *n = next; n; n = n->next) + s << ", " << n->id; +} + +void FuncDeclNode::streamTo(SourceStream &s) const { + s << SourceStream::Endl << "function " << ident << "("; + if (param) + s << param; + s << ")" << body; +} + +void FuncExprNode::streamTo(SourceStream &s) const +{ + s << "function " << "(" + << param + << ")" << body; +} + +void SourceElementsNode::streamTo(SourceStream &s) const +{ + for (const SourceElementsNode *n = this; n; n = n->elements) + s << n->element; +} + |