File indexing completed on 2024-04-14 04:31:38

0001 /* This file is part of kdev-pg-qt
0002    Copyright (C) 2005 Roberto Raggi <roberto@kdevelop.org>
0003    Copyright (C) 2006 Jakob Petsovits <jpetso@gmx.at>
0004    Copyright (C) 2006 Adam Treat <treat@kde.org>
0005 
0006    This library is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Library General Public
0008    License as published by the Free Software Foundation; either
0009    version 2 of the License, or (at your option) any later version.
0010 
0011    This library is distributed in the hope that it will be useful,
0012    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014    Library General Public License for more details.
0015 
0016    You should have received a copy of the GNU Library General Public License
0017    along with this library; see the file COPYING.LIB.  If not, write to
0018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019    Boston, MA 02110-1301, USA.
0020 */
0021 
0022 #include "kdev-pg-serialize-visitor-gen.h"
0023 #include "kdev-pg.h"
0024 
0025 namespace KDevPG
0026 {
0027 
0028 void GenerateSerializeVisitor::operator()()
0029 {
0030   out << "class " << globalSystem.exportMacro << " Serialize: public DefaultVisitor {" << Qt::endl
0031       << "public:" << Qt::endl;
0032 
0033   out << "static void read(KDevPG::MemoryPool *p," << Qt::endl
0034       << "AstNode *node, QIODevice* i) { " << Qt::endl
0035       << "Serialize(p, node, i); " << Qt::endl
0036       << "}" << Qt::endl << Qt::endl;
0037 
0038   out << "static void write(AstNode *node, QIODevice* o) { " << Qt::endl
0039       << "Serialize(node, o); " << Qt::endl
0040       << "}" << Qt::endl << Qt::endl;
0041 
0042   out << "private:" << Qt::endl;
0043   out << "Serialize(KDevPG::MemoryPool *p," << Qt::endl
0044       << "AstNode *node, QIODevice* i) : in(i) {" << Qt::endl
0045       << "memoryPool = p;" << Qt::endl
0046       << "if ( !node )" << Qt::endl
0047       << "node = create<" << (*globalSystem.start.begin())->mCapitalizedName << "Ast>();" << Qt::endl
0048       << "visitNode( node );" << Qt::endl
0049       << "}" << Qt::endl << Qt::endl;
0050 
0051   out << "Serialize(AstNode *node, QIODevice *o) : out(o) {" << Qt::endl
0052       << "visitNode( node );" << Qt::endl
0053       << "}" << Qt::endl << Qt::endl;
0054 
0055   out << "QDataStream in;" << Qt::endl;
0056   out << "QDataStream out;" << Qt::endl << Qt::endl;
0057 
0058   out << "// memory pool" << Qt::endl
0059       << "typedef KDevPG::MemoryPool memoryPoolType;" << Qt::endl
0060       << "KDevPG::MemoryPool *memoryPool;" << Qt::endl
0061       << "template <class T>" << Qt::endl
0062       << "inline T *create() {" << Qt::endl
0063       << "T *node = new (memoryPool->allocate(sizeof(T))) T();" << Qt::endl
0064       << "node->kind = T::KIND;" << Qt::endl
0065       << "return node;" << Qt::endl
0066       << "}" << Qt::endl;
0067 
0068   out << "template <class T, class E>" << Qt::endl
0069       << "void handleListNode(const KDevPG::ListNode<T> *t, E *e) {" << Qt::endl
0070       << "if (in) {" << Qt::endl
0071 
0072       //list in
0073       << "bool b;" << Qt::endl
0074       << "in >> b;" << Qt::endl
0075       << "if (b) {" << Qt::endl
0076       << "qint64 count;" << Qt::endl
0077       << "in >> count;" << Qt::endl
0078       << "for ( qint64 i = 0; i < count; ++i ) {" << Qt::endl
0079       << "    e = create<E>();" << Qt::endl // FIXME: what about token
0080       << "    t = KDevPG::snoc(t, e, memoryPool);" << Qt::endl
0081       << "}" << Qt::endl
0082       << "}" << Qt::endl
0083       //end list in
0084 
0085       << "} else if (out) {" << Qt::endl
0086 
0087       //list out
0088       <<"if (t) {" << Qt::endl
0089       << "out << true;" << Qt::endl
0090       << "out << t->count();" << Qt::endl
0091       << "} else {" << Qt::endl
0092       << "out << false;" << Qt::endl
0093       << "}" << Qt::endl << Qt::endl
0094       //end list out
0095 
0096       << "}" << Qt::endl
0097       << "}" << Qt::endl << Qt::endl;
0098 
0099   out << "template <class T>" << Qt::endl
0100       << "void handleAstNode(T *t) {" << Qt::endl
0101       << "if (in) {" << Qt::endl
0102 
0103       //ast in
0104       << "bool b;" << Qt::endl
0105       << "in >> b;" << Qt::endl
0106       << "if (b) {" << Qt::endl
0107       << "t = create<T>();" << Qt::endl
0108 
0109       << "in >> t->startToken;" << Qt::endl
0110       << "in >> t->endToken;" << Qt::endl
0111       << "}" << Qt::endl
0112       //end ast in
0113 
0114       << "} else if (out) {" << Qt::endl
0115 
0116       //ast out
0117       << "if (t) {" << Qt::endl
0118       << "bool b = true;" << Qt::endl
0119       << "out << true;" << Qt::endl
0120       << "out << t->startToken;" << Qt::endl
0121       << "out << t->endToken;" << Qt::endl
0122       << "} else {" << Qt::endl
0123       << "out << false;" << Qt::endl
0124       << "}" << Qt::endl << Qt::endl
0125       //end ast out
0126 
0127       << "}" << Qt::endl
0128       << "}" << Qt::endl << Qt::endl;
0129 
0130   out << "template <class T>" << Qt::endl
0131       << "void handleVariable(T *t) {" << Qt::endl
0132       << "if (in) {" << Qt::endl
0133       << "in >> t;" << Qt::endl
0134       << "} else if (out) {" << Qt::endl
0135       << "out << t;" << Qt::endl
0136       << "}" << Qt::endl
0137       << "}" << Qt::endl << Qt::endl;
0138 
0139 
0140   GenerateSerializeVisitorRule gen(out);
0141   for( World::SymbolSet::iterator it = globalSystem.symbols.begin();
0142        it != globalSystem.symbols.end(); ++it )
0143   {
0144     gen(qMakePair(it.key(), *it));
0145   }
0146 
0147   out << "};" << Qt::endl;
0148 }
0149 
0150 void GenerateSerializeVisitorRule::operator()(QPair<QString,
0151                                           Model::SymbolItem*> const &__it)
0152 {
0153   mNames.clear();
0154   mVariableDeclarations.clear();
0155 
0156   Model::SymbolItem *sym = __it.second;
0157 
0158   bool has_members = false;
0159   HasMemberNodes hms(has_members);
0160   hms(sym);
0161 
0162   out << "void visit" << sym->mCapitalizedName
0163       << "(" << sym->mCapitalizedName << "Ast *" << "node"
0164       << ") override {" << Qt::endl;
0165 
0166   Model::EvolveItem *e = globalSystem.searchRule(sym);
0167   visitNode(e);
0168   
0169   out << "DefaultVisitor::visit" << sym->mCapitalizedName
0170       << "(" << "node"
0171       << ");" << Qt::endl;
0172 
0173   out << "}" << Qt::endl << Qt::endl;
0174 }
0175 
0176 void GenerateSerializeVisitorRule::visitVariableDeclaration(Model::VariableDeclarationItem *node)
0177 {
0178   do
0179   {
0180     if (node->mStorageType != Model::VariableDeclarationItem::StorageAstMember)
0181       break;
0182 
0183     if (mNames.find(node->mName) != mNames.end())
0184       break;
0185 
0186     QString ext =
0187         ( node->mVariableType == Model::VariableDeclarationItem::TypeNode ?
0188         "Ast" : "");
0189 
0190     QString type = node->mType + ext;
0191     QString name = node->mName;
0192 
0193     if (node->mVariableType == Model::VariableDeclarationItem::TypeToken)
0194       type = "qint64";
0195 
0196     if (node->mIsSequence)
0197     {
0198       out << "{" << Qt::endl
0199           << type << " *e = 0;" << Qt::endl
0200           << "handleListNode(node->" << name << "Sequence, e);" << Qt::endl
0201           << "}" << Qt::endl;
0202     }
0203     else if (node->mVariableType == Model::VariableDeclarationItem::TypeNode)
0204     {
0205       out << "handleAstNode(node->" << name << ");" << Qt::endl;
0206     }
0207     else if (node->mVariableType == Model::VariableDeclarationItem::TypeVariable
0208              || node->mVariableType == Model::VariableDeclarationItem::TypeToken)
0209     {
0210       out << "handleVariable(&node->" << name << ");" << Qt::endl;
0211     }
0212     else
0213     {
0214       Q_ASSERT(0); // every variable type must be supported
0215     }
0216 
0217     mNames.insert(node->mName);
0218     mVariableDeclarations.push_back(node);
0219 
0220   } while(false);
0221 
0222   DefaultVisitor::visitVariableDeclaration(node);
0223 }
0224 
0225 }