diff options
author | Roberto Raggi <roberto.raggi@nokia.com> | 2009-11-13 11:35:19 +0100 |
---|---|---|
committer | Roberto Raggi <roberto.raggi@nokia.com> | 2009-11-13 11:35:19 +0100 |
commit | ecf712e6bc51dd65a0a414d1fa044aba19ab26cf (patch) | |
tree | 5b2112a370770af66dd3a589d430779619bda1a6 /src/tools/cplusplus/Main.cpp | |
parent | 261b8700343980b7da17eed3d00779b44e67e64c (diff) | |
download | qt-creator-ecf712e6bc51dd65a0a414d1fa044aba19ab26cf.tar.gz |
New matchers
Diffstat (limited to 'src/tools/cplusplus/Main.cpp')
-rw-r--r-- | src/tools/cplusplus/Main.cpp | 154 |
1 files changed, 131 insertions, 23 deletions
diff --git a/src/tools/cplusplus/Main.cpp b/src/tools/cplusplus/Main.cpp index 00fc4eea00..c1160cb186 100644 --- a/src/tools/cplusplus/Main.cpp +++ b/src/tools/cplusplus/Main.cpp @@ -55,13 +55,13 @@ static const char copyrightHeader[] = "**************************************************************************/\n" ; -class VisitCG: protected ASTVisitor +class Accept0CG: protected ASTVisitor { QDir _cplusplusDir; QTextStream *out; public: - VisitCG(const QDir &cplusplusDir, Control *control) + Accept0CG(const QDir &cplusplusDir, Control *control) : ASTVisitor(control), _cplusplusDir(cplusplusDir), out(0) { } @@ -194,13 +194,13 @@ protected: } }; -class MatchCG: protected ASTVisitor +class Match0CG: protected ASTVisitor { QDir _cplusplusDir; QTextStream *out; public: - MatchCG(const QDir &cplusplusDir, Control *control) + Match0CG(const QDir &cplusplusDir, Control *control) : ASTVisitor(control), _cplusplusDir(cplusplusDir), out(0) { } @@ -245,10 +245,114 @@ protected: Overview oo; const QString className = oo(klass->name()); - *out << " if (" << className << " *_other = pattern->as" << className.left(className.length() - 3) << "()) {" << endl; + *out << " if (" << className << " *_other = pattern->as" << className.left(className.length() - 3) << "())" << endl; - *out << " if (! matcher->match(this, _other))" << endl - << " return false;" << endl; + *out << " return matcher->match(this, _other);" << endl; + + *out << endl; + } + + bool checkMethod(Symbol *accept0Method) const + { + Declaration *decl = accept0Method->asDeclaration(); + if (! decl) + return false; + + Function *funTy = decl->type()->asFunctionType(); + if (! funTy) + return false; + + else if (funTy->isPureVirtual()) + return false; + + return true; + } + + virtual bool visit(ClassSpecifierAST *ast) + { + Class *klass = ast->symbol; + const QByteArray className = id_cast(ast->name); + + Identifier *match0_id = control()->findOrInsertIdentifier("match0"); + Symbol *accept0Method = klass->members()->lookat(match0_id); + for (; accept0Method; accept0Method = accept0Method->next()) { + if (accept0Method->identifier() != match0_id) + continue; + + if (checkMethod(accept0Method)) + break; + } + + if (! accept0Method) + return true; + + classMap.insert(className, ast); + + *out + << "bool " << className.constData() << "::match0(AST *pattern, ASTMatcher *matcher)" << endl + << "{" << endl; + + visitMembers(klass); + + *out + << " return false;" << endl + << "}" << endl + << endl; + + return true; + } +}; + + +class MatcherCPPCG: protected ASTVisitor +{ + QDir _cplusplusDir; + QTextStream *out; + +public: + MatcherCPPCG(const QDir &cplusplusDir, Control *control) + : ASTVisitor(control), _cplusplusDir(cplusplusDir), out(0) + { } + + void operator()(AST *ast) + { + QFileInfo fileInfo(_cplusplusDir, QLatin1String("ASTMatcher.cpp")); + + QFile file(fileInfo.absoluteFilePath()); + if (! file.open(QFile::WriteOnly)) + return; + + QTextStream output(&file); + out = &output; + + *out << copyrightHeader << + "\n" + "#include \"AST.h\"\n" + "#include \"ASTMatcher.h\"\n" + "\n" + "using namespace CPlusPlus;\n" << endl; + + accept(ast); + } + +protected: + using ASTVisitor::visit; + + QMap<QByteArray, ClassSpecifierAST *> classMap; + + QByteArray id_cast(NameAST *name) + { + if (! name) + return QByteArray(); + + Identifier *id = identifier(name->asSimpleName()->identifier_token); + + return QByteArray::fromRawData(id->chars(), id->size()); + } + + void visitMembers(Class *klass) + { + const QByteArray className = klass->name()->identifier()->chars(); for (unsigned i = 0; i < klass->memberCount(); ++i) { Symbol *member = klass->memberAt(i); @@ -262,7 +366,10 @@ protected: const QByteArray memberName = QByteArray::fromRawData(id->chars(), id->size()); if (member->type().isUnsigned() && memberName.endsWith("_token")) { - // nothing to do here. + // nothing to do. The member is a token. + + *out << " if (node->" << memberName << " != pattern->" << memberName << ")" << endl + << " return false;" << endl; } else if (PointerType *ptrTy = member->type()->asPointerType()) { @@ -270,9 +377,8 @@ protected: QByteArray typeName = namedTy->name()->identifier()->chars(); if (typeName.endsWith("AST")) { - *out << " if (! match(" << memberName << ", _other->" << memberName << ", matcher))" << endl - << " return false;" << endl; - + *out << " if (! AST::match(node->" << memberName << ", pattern->" << memberName << ", this))" << endl + << " return false;" << endl; } } } @@ -285,9 +391,6 @@ protected: visitMembers(baseClassSpec->symbol); } } - - *out << " return true;" << endl; - *out << " }" << endl; } bool checkMethod(Symbol *accept0Method) const @@ -312,28 +415,28 @@ protected: const QByteArray className = id_cast(ast->name); Identifier *match0_id = control()->findOrInsertIdentifier("match0"); - Symbol *accept0Method = klass->members()->lookat(match0_id); - for (; accept0Method; accept0Method = accept0Method->next()) { - if (accept0Method->identifier() != match0_id) + Symbol *match0Method = klass->members()->lookat(match0_id); + for (; match0Method; match0Method = match0Method->next()) { + if (match0Method->identifier() != match0_id) continue; - if (checkMethod(accept0Method)) + if (checkMethod(match0Method)) break; } - if (! accept0Method) + if (! match0Method) return true; classMap.insert(className, ast); *out - << "bool " << className.constData() << "::match0(AST *pattern, ASTMatcher *matcher)" << endl + << "bool ASTMatcher::match(" << className.constData() << " *node, " << className.constData() << " *pattern)" << endl << "{" << endl; visitMembers(klass); *out - << " return false;" << endl + << " return true;" << endl << "}" << endl << endl; @@ -341,6 +444,8 @@ protected: } }; + + QTextCursor createCursor(TranslationUnit *unit, AST *ast, QTextDocument *document) { unsigned startLine, startColumn, endLine, endColumn; @@ -545,12 +650,15 @@ QStringList generateAST_H(const Snapshot &snapshot, const QDir &cplusplusDir) out << document.toPlainText(); } - VisitCG cg(cplusplusDir, doc->control()); + Accept0CG cg(cplusplusDir, doc->control()); cg(doc->translationUnit()->ast()); - MatchCG cg2(cplusplusDir, doc->control()); + Match0CG cg2(cplusplusDir, doc->control()); cg2(doc->translationUnit()->ast()); + MatcherCPPCG cg3(cplusplusDir, doc->control()); + cg3(doc->translationUnit()->ast()); + return astDerivedClasses; } |