File indexing completed on 2024-05-05 13:02:23
0001 /* This file is part of kdev-pg-qt 0002 Copyright (C) 2006 Alexander Dymo <adymo@kdevelop.org> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "kdev-pg-debug-visitor-gen.h" 0021 #include "kdev-pg.h" 0022 #include <iostream> 0023 0024 namespace KDevPG 0025 { 0026 0027 void GenerateDebugVisitor::operator()() 0028 { 0029 // the debug visitor class is header-only, thus we don't need an export macro here 0030 out << "class DebugVisitor: public DefaultVisitor {" << Qt::endl 0031 << "public:" << Qt::endl; 0032 0033 out << "DebugVisitor("<< globalSystem.tokenStream << " *str, const QString& content = QString())" << Qt::endl; 0034 out << " : m_str(str), m_indent(0), m_content(content) {}" << Qt::endl; 0035 GenerateDebugVisitorRule gen(out); 0036 for( World::SymbolSet::iterator it = globalSystem.symbols.begin(); 0037 it != globalSystem.symbols.end(); ++it ) 0038 { 0039 gen(qMakePair(it.key(), *it)); 0040 } 0041 0042 out << "private:" << Qt::endl; 0043 out << "void printToken(const AstNode *node, const QString &mType, const QString &mName = QString())" << Qt::endl; 0044 out << "{" << Qt::endl; 0045 out << " KDevPG::TokenStream::Token startToken;" << Qt::endl; 0046 out << " KDevPG::TokenStream::Token endToken;" << Qt::endl; 0047 out << " qint64 line, column;" << Qt::endl; 0048 out << " const bool isValidStartToken = (0 <= node->startToken && node->startToken < m_str->size());" << Qt::endl; 0049 out << " QString startTokenString;" << Qt::endl; 0050 out << " if (isValidStartToken) {" << Qt::endl; 0051 out << " startToken = m_str->at(node->startToken);" << Qt::endl; 0052 out << " m_str->startPosition(node->startToken, &line, &column);" << Qt::endl; 0053 out << " startTokenString = QString::number(startToken.begin) + QLatin1String(\", \") + QString::number(line) + QLatin1String(\", \") + QString::number(column);" << Qt::endl; 0054 out << " } else {" << Qt::endl; 0055 out << " startTokenString = QLatin1String(\"invalid token index: \") + QString::number(node->startToken);" << Qt::endl; 0056 out << " }" << Qt::endl; 0057 out << " const bool isValidEndToken = (0 <= node->endToken && node->endToken < m_str->size());" << Qt::endl; 0058 out << " QString endTokenString;" << Qt::endl; 0059 out << " if (isValidEndToken) {" << Qt::endl; 0060 out << " endToken = m_str->at(node->endToken);" << Qt::endl; 0061 out << " m_str->startPosition(node->endToken, &line, &column);" << Qt::endl; 0062 out << " endTokenString = QString::number(endToken.begin) + QLatin1String(\", \") + QString::number(line) + QLatin1String(\", \") + QString::number(column);" << Qt::endl; 0063 out << " } else {" << Qt::endl; 0064 out << " endTokenString = QLatin1String(\"invalid token index: \") + QString::number(node->endToken);" << Qt::endl; 0065 out << " }" << Qt::endl; 0066 out << " QString tokenString;" << Qt::endl; 0067 out << " if (!m_content.isEmpty() && isValidStartToken && isValidEndToken) {" << Qt::endl; 0068 out << " const int begin = startToken.begin;" << Qt::endl; 0069 out << " const int end = endToken.end;" << Qt::endl; 0070 out << " if (end-begin > 30) {" << Qt::endl; 0071 out << " tokenString = m_content.mid(begin, 10);" << Qt::endl; 0072 out << " tokenString += QStringLiteral(\" ...\");" << Qt::endl; 0073 out << " tokenString += QStringLiteral(\"%1 more\").arg(end-begin-20);" << Qt::endl; 0074 out << " tokenString += QStringLiteral(\"... \");" << Qt::endl; 0075 out << " tokenString += QStringView(m_content).mid(end-10, 10);" << Qt::endl; 0076 out << " }" << Qt::endl; 0077 out << " else {" << Qt::endl; 0078 out << " tokenString = m_content.mid(begin, end-begin+1);" << Qt::endl; 0079 out << " }" << Qt::endl; 0080 out << " tokenString.replace('\\n', QStringLiteral(\"\\\\n\"));" << Qt::endl; 0081 out << " tokenString.replace('\\r', QStringLiteral(\"\\\\r\"));" << Qt::endl; 0082 out << " }" << Qt::endl; 0083 out << " qDebug() <<" 0084 << " QString(QString().fill(QLatin1Char(' '), m_indent) +" 0085 << " mName + QLatin1String(!mName.isEmpty() ? \"->\" : \"\") + mType +" 0086 << " QLatin1Char('[') + startTokenString + QLatin1String(\"] --- [\") + endTokenString + QLatin1String(\"] \")).toUtf8().constData()" 0087 << " << tokenString;" << Qt::endl; 0088 out << "}" << Qt::endl; 0089 out << globalSystem.tokenStream << " *m_str;" << Qt::endl; 0090 out << "int m_indent;" << Qt::endl; 0091 out << "QString m_content;" << Qt::endl; 0092 out << "};" << Qt::endl; 0093 } 0094 0095 void GenerateDebugVisitorRule::operator()(QPair<QString, 0096 Model::SymbolItem*> const &__it) 0097 { 0098 Model::SymbolItem *sym = __it.second; 0099 mNames.clear(); 0100 0101 bool has_members = false; 0102 HasMemberNodes hms(has_members); 0103 hms(sym); 0104 0105 #define O1(name) \ 0106 out << "void visit" << name \ 0107 << "(" << name << "Ast *" << "node" \ 0108 << ") override {" << Qt::endl; 0109 #define O2(name) \ 0110 out << "printToken(node, QStringLiteral(\"" << name << "\"));" << Qt::endl; 0111 #define O3(name) \ 0112 out << "++m_indent;"; \ 0113 \ 0114 out << "DefaultVisitor::visit" << name \ 0115 << "(" << "node" \ 0116 << ");" << Qt::endl; \ 0117 \ 0118 out << "m_indent--;"; \ 0119 \ 0120 out << "}" << Qt::endl << Qt::endl; 0121 0122 if(isOperatorSymbol(sym)) 0123 { 0124 O1("Prefix" + sym->mCapitalizedName) 0125 O2("prefix-" + sym->mName) 0126 O3("Prefix" + sym->mCapitalizedName) 0127 O1("Postfix" + sym->mCapitalizedName) 0128 O2("postfix-" + sym->mName) 0129 O3("Postfix" + sym->mCapitalizedName) 0130 O1("Binary" + sym->mCapitalizedName) 0131 O2("binary-" + sym->mName) 0132 O3("Binary" + sym->mCapitalizedName) 0133 O1("Ternary" + sym->mCapitalizedName) 0134 O2("ternary-" + sym->mName) 0135 O3("Ternary" + sym->mCapitalizedName) 0136 } 0137 else 0138 { 0139 O1(sym->mCapitalizedName) 0140 O2(sym->mName) 0141 0142 World::Environment::iterator it = globalSystem.env.find(sym); 0143 while (it != globalSystem.env.end()) 0144 { 0145 Model::EvolveItem *e = (*it); 0146 if (it.key() != sym) 0147 break; 0148 0149 ++it; 0150 0151 visitNode(e); 0152 } 0153 O3(sym->mCapitalizedName) 0154 } 0155 0156 #undef O3 0157 #undef O2 0158 #undef O1 0159 0160 } 0161 0162 void GenerateDebugVisitorRule::visitVariableDeclaration(Model::VariableDeclarationItem *node) 0163 { 0164 do 0165 { 0166 if (node->mStorageType != Model::VariableDeclarationItem::StorageAstMember) 0167 break; 0168 0169 if (node->mVariableType != Model::VariableDeclarationItem::TypeNode) 0170 break; // nothing to do 0171 0172 if (mNames.find(node->mName) != mNames.end()) 0173 break; 0174 0175 QString base_type = node->mCapitalizedType + "Ast*"; 0176 0177 if (node->mIsSequence) 0178 { 0179 out << "if (" << "node->" << node->mName << "Sequence" << ") {" 0180 << "const KDevPG::ListNode<" << base_type << "> *__it = " 0181 << "node->" << node->mName << "Sequence" << "->front()" 0182 << ", *__end = __it;" << Qt::endl 0183 << "do {" << Qt::endl 0184 << "printToken(__it->element, QStringLiteral(\"" << node->mType << "\"), QStringLiteral(\"" << node->mName << "[]\"));" << Qt::endl 0185 << "__it = __it->next;" << Qt::endl 0186 << "} while (__it != __end);" << Qt::endl 0187 << "}" << Qt::endl; 0188 } 0189 else 0190 { 0191 out << "if (node->" << node->mName << ") printToken(node->" << node->mName << ", QStringLiteral(\"" << node->mType << "\"), QStringLiteral(\"" << node->mName << "\"));" << Qt::endl; 0192 } 0193 0194 mNames.insert(node->mName); 0195 0196 } while(false); 0197 0198 DefaultVisitor::visitVariableDeclaration(node); 0199 } 0200 }