summaryrefslogtreecommitdiff
path: root/src/tools/cplusplus/Main.cpp
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2009-11-13 11:35:19 +0100
committerRoberto Raggi <roberto.raggi@nokia.com>2009-11-13 11:35:19 +0100
commitecf712e6bc51dd65a0a414d1fa044aba19ab26cf (patch)
tree5b2112a370770af66dd3a589d430779619bda1a6 /src/tools/cplusplus/Main.cpp
parent261b8700343980b7da17eed3d00779b44e67e64c (diff)
downloadqt-creator-ecf712e6bc51dd65a0a414d1fa044aba19ab26cf.tar.gz
New matchers
Diffstat (limited to 'src/tools/cplusplus/Main.cpp')
-rw-r--r--src/tools/cplusplus/Main.cpp154
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;
}