diff options
author | Martin Smith <msmith@trolltech.com> | 2009-11-05 13:09:16 (GMT) |
---|---|---|
committer | David Boddie <dboddie@trolltech.com> | 2009-11-11 18:08:07 (GMT) |
commit | c078c0e0f8d0b32c64a5a95166fa4b8149219c99 (patch) | |
tree | ae8a8785c7c336a2f68160b68873f7cebd75672b /tools | |
parent | c2fcbbb390af64bb749b1e9995cc84d40c8a5ca7 (diff) | |
download | Qt-c078c0e0f8d0b32c64a5a95166fa4b8149219c99.zip Qt-c078c0e0f8d0b32c64a5a95166fa4b8149219c99.tar.gz Qt-c078c0e0f8d0b32c64a5a95166fa4b8149219c99.tar.bz2 |
qdoc3: Fixed a linking problem for qml methods.
Note the Invalid Syntax errors for some uses of
\qmlmethod and \qmlsignal. A syntactically correct
signature is now required as the argument.
Diffstat (limited to 'tools')
-rw-r--r-- | tools/qdoc3/cppcodemarker.cpp | 8 | ||||
-rw-r--r-- | tools/qdoc3/cppcodeparser.cpp | 70 | ||||
-rw-r--r-- | tools/qdoc3/cppcodeparser.h | 14 | ||||
-rw-r--r-- | tools/qdoc3/htmlgenerator.cpp | 4 | ||||
-rw-r--r-- | tools/qdoc3/node.cpp | 92 | ||||
-rw-r--r-- | tools/qdoc3/node.h | 39 | ||||
-rw-r--r-- | tools/qdoc3/tree.cpp | 13 |
7 files changed, 152 insertions, 88 deletions
diff --git a/tools/qdoc3/cppcodemarker.cpp b/tools/qdoc3/cppcodemarker.cpp index c07be8b..f3188bd 100644 --- a/tools/qdoc3/cppcodemarker.cpp +++ b/tools/qdoc3/cppcodemarker.cpp @@ -1154,14 +1154,14 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, } } else if ((*c)->type() == Node::QmlSignal) { - const QmlSignalNode* sn = static_cast<const QmlSignalNode*>(*c); + const FunctionNode* sn = static_cast<const FunctionNode*>(*c); if (sn->isAttached()) insert(qmlattachedsignals,*c,style,Okay); else insert(qmlsignals,*c,style,Okay); } else if ((*c)->type() == Node::QmlMethod) { - const QmlMethodNode* mn = static_cast<const QmlMethodNode*>(*c); + const FunctionNode* mn = static_cast<const FunctionNode*>(*c); if (mn->isAttached()) insert(qmlattachedmethods,*c,style,Okay); else @@ -1193,14 +1193,14 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, insert(qmlproperties,*c,style,Okay); } else if ((*c)->type() == Node::QmlSignal) { - const QmlSignalNode* sn = static_cast<const QmlSignalNode*>(*c); + const FunctionNode* sn = static_cast<const FunctionNode*>(*c); if (sn->isAttached()) insert(qmlattachedsignals,*c,style,Okay); else insert(qmlsignals,*c,style,Okay); } else if ((*c)->type() == Node::QmlMethod) { - const QmlMethodNode* mn = static_cast<const QmlMethodNode*>(*c); + const FunctionNode* mn = static_cast<const FunctionNode*>(*c); if (mn->isAttached()) insert(qmlattachedmethods,*c,style,Okay); else diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index cabbe38..90d83ca 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -693,13 +693,13 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc, if (n && n->subType() == Node::QmlClass) { qmlClass = static_cast<QmlClassNode*>(n); if (command == COMMAND_QMLSIGNAL) - return new QmlSignalNode(qmlClass,name,false); + return makeFunctionNode(doc,arg,qmlClass,Node::QmlSignal,false,COMMAND_QMLSIGNAL); else if (command == COMMAND_QMLATTACHEDSIGNAL) - return new QmlSignalNode(qmlClass,name,true); + return makeFunctionNode(doc,arg,qmlClass,Node::QmlSignal,true,COMMAND_QMLATTACHEDSIGNAL); else if (command == COMMAND_QMLMETHOD) - return new QmlMethodNode(qmlClass,name,false); + return makeFunctionNode(doc,arg,qmlClass,Node::QmlMethod,false,COMMAND_QMLMETHOD); else if (command == COMMAND_QMLATTACHEDMETHOD) - return new QmlMethodNode(qmlClass,name,true); + return makeFunctionNode(doc,arg,qmlClass,Node::QmlMethod,true,COMMAND_QMLATTACHEDMETHOD); else return 0; // never get here. } @@ -1265,7 +1265,9 @@ bool CppCodeParser::matchParameter(FunctionNode *func) bool CppCodeParser::matchFunctionDecl(InnerNode *parent, QStringList *parentPathPtr, FunctionNode **funcPtr, - const QString &templateStuff) + const QString &templateStuff, + Node::Type type, + bool attached) { CodeChunk returnType; QStringList parentPath; @@ -1295,8 +1297,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, if (tokenizer->parsingFnOrMacro() && (match(Tok_Q_DECLARE_FLAGS) || match(Tok_Q_PROPERTY))) returnType = CodeChunk(previousLexeme()); - else + else { return false; + } } if (returnType.toString() == "QBool") @@ -1326,8 +1329,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, readToken(); } } - if (tok != Tok_LeftParen) + if (tok != Tok_LeftParen) { return false; + } } else if (tok == Tok_LeftParen) { // constructor or destructor @@ -1373,8 +1377,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, returnType.append(lexeme()); readToken(); } - if (tok != Tok_Semicolon) + if (tok != Tok_Semicolon) { return false; + } } else if (tok == Tok_Colon) { returnType.appendHotspot(); @@ -1383,8 +1388,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, returnType.append(lexeme()); readToken(); } - if (tok != Tok_Semicolon) + if (tok != Tok_Semicolon) { return false; + } } VariableNode *var = new VariableNode(parent, name); @@ -1397,12 +1403,13 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, var->setStatic(sta); return false; } - if (tok != Tok_LeftParen) + if (tok != Tok_LeftParen) { return false; + } } readToken(); - FunctionNode *func = new FunctionNode(parent, name); + FunctionNode *func = new FunctionNode(type, parent, name, attached); func->setAccess(access); func->setLocation(location()); func->setReturnType(returnType.toString()); @@ -1423,12 +1430,14 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, if (tok != Tok_RightParen) { do { - if (!matchParameter(func)) + if (!matchParameter(func)) { return false; + } } while (match(Tok_Comma)); } - if (!match(Tok_RightParen)) + if (!match(Tok_RightParen)) { return false; + } func->setConst(match(Tok_const)); @@ -1444,8 +1453,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, if (!match(Tok_Semicolon) && tok != Tok_Eoi) { int braceDepth0 = tokenizer->braceDepth(); - if (!match(Tok_LeftBrace)) + if (!match(Tok_LeftBrace)) { return false; + } while (tokenizer->braceDepth() >= braceDepth0 && tok != Tok_Eoi) readToken(); match(Tok_RightBrace); @@ -2092,7 +2102,9 @@ bool CppCodeParser::matchDocsAndStuff() bool CppCodeParser::makeFunctionNode(const QString& synopsis, QStringList *parentPathPtr, FunctionNode **funcPtr, - InnerNode *root) + InnerNode *root, + Node::Type type, + bool attached) { Tokenizer *outerTokenizer = tokenizer; int outerTok = tok; @@ -2104,15 +2116,39 @@ bool CppCodeParser::makeFunctionNode(const QString& synopsis, tokenizer = &stringTokenizer; readToken(); - bool ok = matchFunctionDecl(root, parentPathPtr, funcPtr); + bool ok = matchFunctionDecl(root, parentPathPtr, funcPtr, QString(), type, attached); // potential memory leak with funcPtr tokenizer = outerTokenizer; tok = outerTok; - return ok; } +/*! + Create a new FunctionNode for a QML method or signal, as + specified by \a type, as a child of \a parent. \a sig is + the complete signature, and if \a attached is true, the + method or signal is "attached". \a qdoctag is the text of + the \a type. + */ +FunctionNode* CppCodeParser::makeFunctionNode(const Doc& doc, + const QString& sig, + InnerNode* parent, + Node::Type type, + bool attached, + QString qdoctag) +{ + QStringList pp; + FunctionNode* fn = 0; + if (!makeFunctionNode(sig,&pp,&fn,parent,type,attached) && + !makeFunctionNode("void "+sig,&pp,&fn,parent,type,attached)) { + doc.location().warning(tr("Invalid syntax in '\\%1'").arg(qdoctag)); + } + if (fn) + return fn; + return 0; +} + void CppCodeParser::parseQiteratorDotH(const Location &location, const QString &filePath) { diff --git a/tools/qdoc3/cppcodeparser.h b/tools/qdoc3/cppcodeparser.h index 233ac09..87c1b69 100644 --- a/tools/qdoc3/cppcodeparser.h +++ b/tools/qdoc3/cppcodeparser.h @@ -127,7 +127,9 @@ class CppCodeParser : public CodeParser bool matchFunctionDecl(InnerNode *parent, QStringList *parentPathPtr = 0, FunctionNode **funcPtr = 0, - const QString &templateStuff = QString()); + const QString &templateStuff = QString(), + Node::Type type = Node::Function, + bool attached = false); bool matchBaseSpecifier(ClassNode *classe, bool isClass); bool matchBaseList(ClassNode *classe, bool isClass); bool matchClassDecl(InnerNode *parent, @@ -143,7 +145,15 @@ class CppCodeParser : public CodeParser bool makeFunctionNode(const QString &synopsis, QStringList *parentPathPtr, FunctionNode **funcPtr, - InnerNode *root = 0); + InnerNode *root = 0, + Node::Type type = Node::Function, + bool attached = false); + FunctionNode* makeFunctionNode(const Doc& doc, + const QString& sig, + InnerNode* parent, + Node::Type type, + bool attached, + QString qdoctag); void parseQiteratorDotH(const Location &location, const QString &filePath); void instantiateIteratorMacro(const QString &container, const QString &includeFile, diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index afd1e74..ae47fc0 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -4219,7 +4219,7 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node, out() << "</div>"; } else if (node->type() == Node::QmlSignal) { - const QmlSignalNode* qsn = static_cast<const QmlSignalNode*>(node); + const FunctionNode* qsn = static_cast<const FunctionNode*>(node); out() << "<div class=\"qmlproto\">"; out() << "<table class=\"qmlname\">"; out() << "<tr><td>"; @@ -4230,7 +4230,7 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node, out() << "</div>"; } else if (node->type() == Node::QmlMethod) { - const QmlMethodNode* qmn = static_cast<const QmlMethodNode*>(node); + const FunctionNode* qmn = static_cast<const FunctionNode*>(node); out() << "<div class=\"qmlproto\">"; out() << "<table class=\"qmlname\">"; out() << "<tr><td>"; diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index ecb4a44..1217042 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -218,6 +218,7 @@ Node *InnerNode::findNode(const QString& name, Type type) } /*! + Find the function node in this node for the function named \a name. */ FunctionNode *InnerNode::findFunctionNode(const QString& name) { @@ -225,6 +226,7 @@ FunctionNode *InnerNode::findFunctionNode(const QString& name) } /*! + Find the function node in this node that has the same name as \a clone. */ FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone) { @@ -248,6 +250,34 @@ FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone) } /*! + Returns the list of keys from the primary function map. + */ +QStringList InnerNode::primaryKeys() +{ + QStringList t; + QMap<QString, Node*>::iterator i = primaryFunctionMap.begin(); + while (i != primaryFunctionMap.end()) { + t.append(i.key()); + ++i; + } + return t; +} + +/*! + Returns the list of keys from the secondary function map. + */ +QStringList InnerNode::secondaryKeys() +{ + QStringList t; + QMap<QString, NodeList>::iterator i = secondaryFunctionMap.begin(); + while (i != secondaryFunctionMap.end()) { + t.append(i.key()); + ++i; + } + return t; +} + +/*! */ void InnerNode::setOverload(const FunctionNode *func, bool overlode) { @@ -392,6 +422,7 @@ const Node *InnerNode::findNode(const QString& name, Type type) const } /*! + Find the function node in this node that has the given \a name. */ const FunctionNode *InnerNode::findFunctionNode(const QString& name) const { @@ -400,9 +431,9 @@ const FunctionNode *InnerNode::findFunctionNode(const QString& name) const } /*! + Find the function node in this node that has the same name as \a clone. */ -const FunctionNode *InnerNode::findFunctionNode( - const FunctionNode *clone) const +const FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone) const { InnerNode *that = (InnerNode *) this; return that->findFunctionNode(clone); @@ -520,7 +551,7 @@ bool InnerNode::isSameSignature(const FunctionNode *f1, const FunctionNode *f2) void InnerNode::addChild(Node *child) { children.append(child); - if (child->type() == Function) { + if ((child->type() == Function) || (child->type() == QmlMethod)) { FunctionNode *func = (FunctionNode *) child; if (!primaryFunctionMap.contains(func->name())) { primaryFunctionMap.insert(func->name(), func); @@ -896,11 +927,40 @@ QString Parameter::reconstruct(bool value) const */ /*! + Construct a function node for a C++ function. It's parent + is \a parent, and it's name is \a name. */ FunctionNode::FunctionNode(InnerNode *parent, const QString& name) - : LeafNode(Function, parent, name), met(Plain), vir(NonVirtual), - con(false), sta(false), ove(false), rf(0), ap(0) + : LeafNode(Function, parent, name), + met(Plain), + vir(NonVirtual), + con(false), + sta(false), + ove(false), + att(false), + rf(0), + ap(0) +{ + // nothing. +} + +/*! + Construct a function node for a QML method or signal, specified + by \a type. It's parent is \a parent, and it's name is \a name. + If \a attached is true, it is an attached method or signal. + */ +FunctionNode::FunctionNode(Type type, InnerNode *parent, const QString& name, bool attached) + : LeafNode(type, parent, name), + met(Plain), + vir(NonVirtual), + con(false), + sta(false), + ove(false), + att(attached), + rf(0), + ap(0) { + // nothing. } /*! @@ -1208,28 +1268,6 @@ bool QmlPropertyNode::fromTrool(Trool troolean, bool defaultValue) return defaultValue; } } - -/*! - Constructor for the QML signal node. - */ -QmlSignalNode::QmlSignalNode(QmlClassNode *parent, - const QString& name, - bool attached) - : LeafNode(QmlSignal, parent, name), att(attached) -{ - // nothing. -} - -/*! - Constructor for the QML method node. - */ -QmlMethodNode::QmlMethodNode(QmlClassNode *parent, - const QString& name, - bool attached) - : LeafNode(QmlMethod, parent, name), att(attached) -{ - // nothing. -} #endif QT_END_NAMESPACE diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h index 5712879..3f5be6c 100644 --- a/tools/qdoc3/node.h +++ b/tools/qdoc3/node.h @@ -151,6 +151,7 @@ class Node virtual bool isInnerNode() const = 0; virtual bool isReimp() const { return false; } + virtual bool isFunction() const { return false; } Type type() const { return typ; } virtual SubType subType() const { return NoSubType; } InnerNode *parent() const { return par; } @@ -239,6 +240,9 @@ class InnerNode : public Node NodeList overloads(const QString &funcName) const; const QStringList& includes() const { return inc; } + QStringList primaryKeys(); + QStringList secondaryKeys(); + protected: InnerNode(Type type, InnerNode *parent, const QString& name); @@ -421,36 +425,6 @@ class QmlPropertyNode : public LeafNode Trool wri; bool att; }; - -class QmlSignalNode : public LeafNode -{ - public: - QmlSignalNode(QmlClassNode* parent, - const QString& name, - bool attached); - virtual ~QmlSignalNode() { } - - const QString& element() const { return parent()->name(); } - bool isAttached() const { return att; } - - private: - bool att; -}; - -class QmlMethodNode : public LeafNode -{ - public: - QmlMethodNode(QmlClassNode* parent, - const QString& name, - bool attached); - virtual ~QmlMethodNode() { } - - const QString& element() const { return parent()->name(); } - bool isAttached() const { return att; } - - private: - bool att; -}; #endif class EnumItem @@ -564,6 +538,7 @@ class FunctionNode : public LeafNode enum Virtualness { NonVirtual, ImpureVirtual, PureVirtual }; FunctionNode(InnerNode *parent, const QString &name); + FunctionNode(Type type, InnerNode *parent, const QString &name, bool attached); virtual ~FunctionNode() { } void setReturnType(const QString& returnType) { rt = returnType; } @@ -589,6 +564,7 @@ class FunctionNode : public LeafNode bool isStatic() const { return sta; } bool isOverload() const { return ove; } bool isReimp() const { return reimp; } + bool isFunction() const { return true; } int overloadNumber() const; int numOverloads() const; const QList<Parameter>& parameters() const { return params; } @@ -600,6 +576,8 @@ class FunctionNode : public LeafNode QStringList reconstructParams(bool values = false) const; QString signature(bool values = false) const; + const QString& element() const { return parent()->name(); } + bool isAttached() const { return att; } private: void setAssociatedProperty(PropertyNode *property); @@ -620,6 +598,7 @@ class FunctionNode : public LeafNode bool sta : 1; bool ove : 1; bool reimp: 1; + bool att: 1; QList<Parameter> params; const FunctionNode *rf; const PropertyNode *ap; diff --git a/tools/qdoc3/tree.cpp b/tools/qdoc3/tree.cpp index bcd9709..4d401de 100644 --- a/tools/qdoc3/tree.cpp +++ b/tools/qdoc3/tree.cpp @@ -225,6 +225,7 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &path, { if (!relative) relative = root(); + do { const Node *node = relative; int i; @@ -244,8 +245,7 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &path, NodeList baseClasses = allBaseClasses(static_cast<const ClassNode *>(node)); foreach (const Node *baseClass, baseClasses) { if (i == path.size() - 1) - next = static_cast<const InnerNode *>(baseClass)-> - findFunctionNode(path.at(i)); + next = static_cast<const InnerNode *>(baseClass)->findFunctionNode(path.at(i)); else next = static_cast<const InnerNode *>(baseClass)->findNode(path.at(i)); @@ -256,11 +256,10 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &path, node = next; } - if (node && i == path.size() && node->type() == Node::Function) { + if (node && i == path.size() && node->isFunction()) { // CppCodeParser::processOtherMetaCommand ensures that reimplemented // functions are private. const FunctionNode *func = static_cast<const FunctionNode*>(node); - while (func->access() == Node::Private) { const FunctionNode *from = func->reimplementedFrom(); if (from != 0) { @@ -268,7 +267,8 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &path, return from; else func = from; - } else + } + else break; } return func; @@ -303,7 +303,8 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &parentPath, const Node *parent = findNode(parentPath, relative, findFlags); if (parent == 0 || !parent->isInnerNode()) { return 0; - } else { + } + else { return ((InnerNode *)parent)->findFunctionNode(clone); } } |