File indexing completed on 2024-04-28 15:54:30
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 {" << endl 0031 << "public:" << endl; 0032 0033 out << "static void read(KDevPG::MemoryPool *p," << endl 0034 << "AstNode *node, QIODevice* i) { " << endl 0035 << "Serialize(p, node, i); " << endl 0036 << "}" << endl << endl; 0037 0038 out << "static void write(AstNode *node, QIODevice* o) { " << endl 0039 << "Serialize(node, o); " << endl 0040 << "}" << endl << endl; 0041 0042 out << "private:" << endl; 0043 out << "Serialize(KDevPG::MemoryPool *p," << endl 0044 << "AstNode *node, QIODevice* i) : in(i) {" << endl 0045 << "memoryPool = p;" << endl 0046 << "if ( !node )" << endl 0047 << "node = create<" << (*globalSystem.start.begin())->mCapitalizedName << "Ast>();" << endl 0048 << "visitNode( node );" << endl 0049 << "}" << endl << endl; 0050 0051 out << "Serialize(AstNode *node, QIODevice *o) : out(o) {" << endl 0052 << "visitNode( node );" << endl 0053 << "}" << endl << endl; 0054 0055 out << "QDataStream in;" << endl; 0056 out << "QDataStream out;" << endl << endl; 0057 0058 out << "// memory pool" << endl 0059 << "typedef KDevPG::MemoryPool memoryPoolType;" << endl 0060 << "KDevPG::MemoryPool *memoryPool;" << endl 0061 << "template <class T>" << endl 0062 << "inline T *create() {" << endl 0063 << "T *node = new (memoryPool->allocate(sizeof(T))) T();" << endl 0064 << "node->kind = T::KIND;" << endl 0065 << "return node;" << endl 0066 << "}" << endl; 0067 0068 out << "template <class T, class E>" << endl 0069 << "void handleListNode(const KDevPG::ListNode<T> *t, E *e) {" << endl 0070 << "if (in) {" << endl 0071 0072 //list in 0073 << "bool b;" << endl 0074 << "in >> b;" << endl 0075 << "if (b) {" << endl 0076 << "qint64 count;" << endl 0077 << "in >> count;" << endl 0078 << "for ( qint64 i = 0; i < count; ++i ) {" << endl 0079 << " e = create<E>();" << endl // FIXME: what about token 0080 << " t = KDevPG::snoc(t, e, memoryPool);" << endl 0081 << "}" << endl 0082 << "}" << endl 0083 //end list in 0084 0085 << "} else if (out) {" << endl 0086 0087 //list out 0088 <<"if (t) {" << endl 0089 << "out << true;" << endl 0090 << "out << t->count();" << endl 0091 << "} else {" << endl 0092 << "out << false;" << endl 0093 << "}" << endl << endl 0094 //end list out 0095 0096 << "}" << endl 0097 << "}" << endl << endl; 0098 0099 out << "template <class T>" << endl 0100 << "void handleAstNode(T *t) {" << endl 0101 << "if (in) {" << endl 0102 0103 //ast in 0104 << "bool b;" << endl 0105 << "in >> b;" << endl 0106 << "if (b) {" << endl 0107 << "t = create<T>();" << endl 0108 0109 << "in >> t->startToken;" << endl 0110 << "in >> t->endToken;" << endl 0111 << "}" << endl 0112 //end ast in 0113 0114 << "} else if (out) {" << endl 0115 0116 //ast out 0117 << "if (t) {" << endl 0118 << "bool b = true;" << endl 0119 << "out << true;" << endl 0120 << "out << t->startToken;" << endl 0121 << "out << t->endToken;" << endl 0122 << "} else {" << endl 0123 << "out << false;" << endl 0124 << "}" << endl << endl 0125 //end ast out 0126 0127 << "}" << endl 0128 << "}" << endl << endl; 0129 0130 out << "template <class T>" << endl 0131 << "void handleVariable(T *t) {" << endl 0132 << "if (in) {" << endl 0133 << "in >> t;" << endl 0134 << "} else if (out) {" << endl 0135 << "out << t;" << endl 0136 << "}" << endl 0137 << "}" << endl << 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 << "};" << 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 {" << endl; 0165 0166 Model::EvolveItem *e = globalSystem.searchRule(sym); 0167 visitNode(e); 0168 0169 out << "DefaultVisitor::visit" << sym->mCapitalizedName 0170 << "(" << "node" 0171 << ");" << endl; 0172 0173 out << "}" << endl << 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 << "{" << endl 0199 << type << " *e = 0;" << endl 0200 << "handleListNode(node->" << name << "Sequence, e);" << endl 0201 << "}" << endl; 0202 } 0203 else if (node->mVariableType == Model::VariableDeclarationItem::TypeNode) 0204 { 0205 out << "handleAstNode(node->" << name << ");" << endl; 0206 } 0207 else if (node->mVariableType == Model::VariableDeclarationItem::TypeVariable 0208 || node->mVariableType == Model::VariableDeclarationItem::TypeToken) 0209 { 0210 out << "handleVariable(&node->" << name << ");" << 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 }