diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/tools/qlist.cpp | 2 | ||||
-rw-r--r-- | src/tools/qdoc/codeparser.h | 1 | ||||
-rw-r--r-- | src/tools/qdoc/cppcodemarker.cpp | 8 | ||||
-rw-r--r-- | src/tools/qdoc/cppcodeparser.cpp | 74 | ||||
-rw-r--r-- | src/tools/qdoc/cppcodeparser.h | 16 | ||||
-rw-r--r-- | src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc | 9 | ||||
-rw-r--r-- | src/tools/qdoc/generator.cpp | 18 | ||||
-rw-r--r-- | src/tools/qdoc/node.cpp | 101 | ||||
-rw-r--r-- | src/tools/qdoc/node.h | 26 | ||||
-rw-r--r-- | src/tools/qdoc/qdocdatabase.cpp | 53 | ||||
-rw-r--r-- | src/tools/qdoc/qdocdatabase.h | 11 | ||||
-rw-r--r-- | src/tools/qdoc/qdocindexfiles.cpp | 2 | ||||
-rw-r--r-- | src/tools/qdoc/qmlvisitor.cpp | 4 | ||||
-rw-r--r-- | src/tools/qdoc/tokenizer.cpp | 1 | ||||
-rw-r--r-- | src/tools/qdoc/tree.cpp | 17 | ||||
-rw-r--r-- | src/tools/qdoc/tree.h | 6 |
16 files changed, 238 insertions, 111 deletions
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index 509afadfc2..8ed0da7ca0 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -378,7 +378,7 @@ void **QListData::erase(void **xi) references into a QVector and non-heap-allocating QLists. Internally, QList\<T\> is represented as an array of T if - If \c{sizeof(T) <= sizeof(void*)} and T has been declared to be + \c{sizeof(T) <= sizeof(void*)} and T has been declared to be either a \c{Q_MOVABLE_TYPE} or a \c{Q_PRIMITIVE_TYPE} using \l {Q_DECLARE_TYPEINFO}. Otherwise, QList\<T\> is represented as an array of T* and the items are allocated on the heap. diff --git a/src/tools/qdoc/codeparser.h b/src/tools/qdoc/codeparser.h index 379deb7e23..9d9e9286ec 100644 --- a/src/tools/qdoc/codeparser.h +++ b/src/tools/qdoc/codeparser.h @@ -40,7 +40,6 @@ QT_BEGIN_NAMESPACE class Config; -class Node; class QString; class QDocDatabase; diff --git a/src/tools/qdoc/cppcodemarker.cpp b/src/tools/qdoc/cppcodemarker.cpp index 868b249290..774ff115b9 100644 --- a/src/tools/qdoc/cppcodemarker.cpp +++ b/src/tools/qdoc/cppcodemarker.cpp @@ -157,11 +157,11 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, synopsis += "("; if (!func->parameters().isEmpty()) { //synopsis += QLatin1Char(' '); - QList<Parameter>::ConstIterator p = func->parameters().constBegin(); + QVector<Parameter>::ConstIterator p = func->parameters().constBegin(); while (p != func->parameters().constEnd()) { if (p != func->parameters().constBegin()) synopsis += ", "; - synopsis += typified((*p).leftType()); + synopsis += typified((*p).dataType()); if (style != Subpage && !(*p).name().isEmpty()) synopsis += "<@param>" + protect((*p).name()) + "</@param>"; @@ -328,11 +328,11 @@ QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary) synopsis = name; synopsis += QLatin1Char('('); if (!func->parameters().isEmpty()) { - QList<Parameter>::ConstIterator p = func->parameters().constBegin(); + QVector<Parameter>::ConstIterator p = func->parameters().constBegin(); while (p != func->parameters().constEnd()) { if (p != func->parameters().constBegin()) synopsis += ", "; - synopsis += typified((*p).leftType()); + synopsis += typified((*p).dataType()); if (!(*p).name().isEmpty()) { if (!synopsis.endsWith(QLatin1Char('('))) synopsis += QLatin1Char(' '); diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp index cab416370a..8d9596c10b 100644 --- a/src/tools/qdoc/cppcodeparser.cpp +++ b/src/tools/qdoc/cppcodeparser.cpp @@ -54,6 +54,7 @@ static bool inMacroCommand_ = false; static bool parsingHeaderFile_ = false; QStringList CppCodeParser::exampleFiles; QStringList CppCodeParser::exampleDirs; +CppCodeParser* CppCodeParser::cppParser_ = 0; /*! The constructor initializes some regular expressions @@ -63,6 +64,7 @@ CppCodeParser::CppCodeParser() : varComment("/\\*\\s*([a-zA-Z_0-9]+)\\s*\\*/"), sep("(?:<[^>]+>)?::") { reset(); + cppParser_ = this; } /*! @@ -374,12 +376,12 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, } else { func->setMetaness(FunctionNode::MacroWithParams); - QList<Parameter> params = func->parameters(); + QVector<Parameter> params = func->parameters(); for (int i = 0; i < params.size(); ++i) { Parameter ¶m = params[i]; - if (param.name().isEmpty() && !param.leftType().isEmpty() - && param.leftType() != "...") - param = Parameter("", "", param.leftType()); + if (param.name().isEmpty() && !param.dataType().isEmpty() + && param.dataType() != "...") + param = Parameter("", "", param.dataType()); } func->setParameters(params); } @@ -1308,23 +1310,23 @@ bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var) /*! Parse the next function parameter, if there is one, and - append it to parameter list \a p. Return true if a parameter - is parsed and appended to \a p. Otherwise return false. + append it to parameter vector \a pvect. Return true if + a parameter is parsed and appended to \a pvect. + Otherwise return false. */ -bool CppCodeParser::matchParameter(ParsedParameterList& pplist) +bool CppCodeParser::matchParameter(QVector<Parameter>& pvect, bool& isQPrivateSignal) { - ParsedParameter pp; if (match(Tok_QPrivateSignal)) { - pp.qPrivateSignal_ = true; - pplist.append(pp); + isQPrivateSignal = true; return true; } + Parameter p; CodeChunk chunk; - if (!matchDataType(&chunk, &pp.name_)) { + if (!matchDataType(&chunk, &p.name_)) { return false; } - pp.dataType_ = chunk.toString(); + p.dataType_ = chunk.toString(); chunk.clear(); match(Tok_Comment); if (match(Tok_Equal)) { @@ -1336,8 +1338,8 @@ bool CppCodeParser::matchParameter(ParsedParameterList& pplist) readToken(); } } - pp.defaultValue_ = chunk.toString(); - pplist.append(pp); + p.defaultValue_ = chunk.toString(); + pvect.append(p); return true; } @@ -1542,10 +1544,11 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent, readToken(); // A left paren was seen. Parse the parameters - ParsedParameterList pplist; + bool isQPrivateSignal = false; + QVector<Parameter> pvect; if (tok != Tok_RightParen) { do { - if (!matchParameter(pplist)) + if (!matchParameter(pvect, isQPrivateSignal)) return false; } while (match(Tok_Comma)); } @@ -1629,13 +1632,10 @@ bool CppCodeParser::matchFunctionDecl(Aggregate *parent, func->setStatic(matched_static); func->setConst(matchedConst); func->setVirtualness(virtuality); - if (!pplist.isEmpty()) { - foreach (const ParsedParameter& pp, pplist) { - if (pp.qPrivateSignal_) - func->setPrivateSignal(); - else - func->addParameter(Parameter(pp.dataType_, "", pp.name_, pp.defaultValue_)); - } + if (isQPrivateSignal) + func->setPrivateSignal(); + if (!pvect.isEmpty()) { + func->setParameters(pvect); } } if (parentPathPtr != 0) @@ -2417,6 +2417,34 @@ bool CppCodeParser::makeFunctionNode(const QString& signature, } /*! + This function uses a Tokenizer to parse the \a parameters of a + function into the parameter vector \a {pvect}. + */ +bool CppCodeParser::parseParameters(const QString& parameters, + QVector<Parameter>& pvect, + bool& isQPrivateSignal) +{ + Tokenizer* outerTokenizer = tokenizer; + int outerTok = tok; + + QByteArray latin1 = parameters.toLatin1(); + Tokenizer stringTokenizer(Location(), latin1); + stringTokenizer.setParsingFnOrMacro(true); + tokenizer = &stringTokenizer; + readToken(); + + inMacroCommand_ = false; + do { + if (!matchParameter(pvect, isQPrivateSignal)) + return false; + } while (match(Tok_Comma)); + + tokenizer = outerTokenizer; + tok = outerTok; + return true; +} + +/*! 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 diff --git a/src/tools/qdoc/cppcodeparser.h b/src/tools/qdoc/cppcodeparser.h index 733418e27a..ec04482321 100644 --- a/src/tools/qdoc/cppcodeparser.h +++ b/src/tools/qdoc/cppcodeparser.h @@ -51,16 +51,6 @@ class CppCodeParser : public CodeParser { Q_DECLARE_TR_FUNCTIONS(QDoc::CppCodeParser) - struct ParsedParameter { - bool qPrivateSignal_; - QString dataType_; - QString name_; - QString defaultValue_; - ParsedParameter() : qPrivateSignal_(false) { } - }; - friend class QTypeInfo<ParsedParameter>; - typedef QVector<ParsedParameter> ParsedParameterList; - struct ExtraFuncData { Aggregate* root; // Used as the parent. Node::NodeType type; // The node type: Function, etc. @@ -74,6 +64,7 @@ class CppCodeParser : public CodeParser public: CppCodeParser(); ~CppCodeParser(); + static CppCodeParser* cppParser() { return cppParser_; } virtual void initializeParser(const Config& config) Q_DECL_OVERRIDE; virtual void terminateParser() Q_DECL_OVERRIDE; @@ -84,6 +75,7 @@ public: virtual void parseSourceFile(const Location& location, const QString& filePath) Q_DECL_OVERRIDE; virtual void doneParsingHeaderFiles() Q_DECL_OVERRIDE; virtual void doneParsingSourceFiles() Q_DECL_OVERRIDE; + bool parseParameters(const QString& parameters, QVector<Parameter>& pvect, bool& isQPrivateSignal); protected: const QSet<QString>& topicCommands(); @@ -126,7 +118,7 @@ protected: bool matchTemplateAngles(CodeChunk *type = 0); bool matchTemplateHeader(); bool matchDataType(CodeChunk *type, QString *var = 0); - bool matchParameter(ParsedParameterList& pplist); + bool matchParameter(QVector<Parameter>& pvect, bool& isQPrivateSignal); bool matchFunctionDecl(Aggregate *parent, QStringList *parentPathPtr, FunctionNode **funcPtr, @@ -184,10 +176,10 @@ protected: static QStringList exampleFiles; static QStringList exampleDirs; + static CppCodeParser* cppParser_; QString exampleNameFilter; QString exampleImageFilter; }; -Q_DECLARE_TYPEINFO(CppCodeParser::ParsedParameter, Q_MOVABLE_TYPE); #define COMMAND_ABSTRACT Doc::alias("abstract") #define COMMAND_CLASS Doc::alias("class") diff --git a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc index 0f9ca463bb..49cbfc0654 100644 --- a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc @@ -1839,8 +1839,13 @@ \li \c {\l QWidget} - The name of a class documented with the \l {class-command} {\\class} command. - \li \c {\l QWidget::sizeHint()} - The name of a member function, - documented with or without an \l {fn-command} {\\fn} command. + \li \c {\l QWidget::sizeHint()} - The signature of a function without + parameters. If a matching function without parameters can't be found, + the link is satisfied with the first matching function found. + + \li \c {\l QWidget::removeAction(QAction* action)} - The signature + of a function with parameters. If an exact match is not found, the + link is not satisfied and qdoc reports a \e {Can't link to...} error. \li \c {\l <QtGlobal>} - The subject of a \l {headerfile-command} {\\headerfile} command. diff --git a/src/tools/qdoc/generator.cpp b/src/tools/qdoc/generator.cpp index 5153b0de5c..7dfbbb1cb8 100644 --- a/src/tools/qdoc/generator.cpp +++ b/src/tools/qdoc/generator.cpp @@ -804,9 +804,9 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) else if (node->type() == Node::Function) { const FunctionNode *func = static_cast<const FunctionNode *>(node); QSet<QString> definedParams; - QList<Parameter>::ConstIterator p = func->parameters().constBegin(); + QVector<Parameter>::ConstIterator p = func->parameters().constBegin(); while (p != func->parameters().constEnd()) { - if ((*p).name().isEmpty() && (*p).leftType() != QLatin1String("...") + if ((*p).name().isEmpty() && (*p).dataType() != QLatin1String("...") && func->name() != QLatin1String("operator++") && func->name() != QLatin1String("operator--")) { node->doc().location().warning(tr("Missing parameter name")); @@ -836,7 +836,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) else if (!(*a).isEmpty() && !documentedParams.contains(*a)) { bool needWarning = (func->status() > Node::Obsolete); if (func->overloadNumber() > 0) { - FunctionNode *primaryFunc = func->parent()->findFunctionNode(func->name()); + FunctionNode *primaryFunc = func->parent()->findFunctionNode(func->name(), QString()); if (primaryFunc) { foreach (const Parameter ¶m, primaryFunc->parameters()) { @@ -1504,7 +1504,7 @@ void Generator::generateOverloadedSignal(const Node* node, CodeMarker* marker) if (i != 0) code += ", "; const Parameter &p = func->parameters().at(i); - code += p.leftType() + p.rightType(); + code += p.dataType() + p.rightType(); } code += ")"; @@ -1516,7 +1516,7 @@ void Generator::generateOverloadedSignal(const Node* node, CodeMarker* marker) if (i != 0) code += ", "; const Parameter &p = func->parameters().at(i); - code += p.leftType(); + code += p.dataType(); if (code[code.size()-1].isLetterOrNumber()) code += " "; code += p.name() + p.rightType(); @@ -2049,14 +2049,14 @@ void Generator::supplementAlsoList(const Node *node, QList<Text> &alsoList) if (func->name().startsWith("set") && func->name().size() >= 4) { alternateName = func->name()[3].toLower(); alternateName += func->name().mid(4); - alternateFunc = func->parent()->findFunctionNode(alternateName); + alternateFunc = func->parent()->findFunctionNode(alternateName, QString()); if (!alternateFunc) { alternateName = "is" + func->name().mid(3); - alternateFunc = func->parent()->findFunctionNode(alternateName); + alternateFunc = func->parent()->findFunctionNode(alternateName, QString()); if (!alternateFunc) { alternateName = "has" + func->name().mid(3); - alternateFunc = func->parent()->findFunctionNode(alternateName); + alternateFunc = func->parent()->findFunctionNode(alternateName, QString()); } } } @@ -2064,7 +2064,7 @@ void Generator::supplementAlsoList(const Node *node, QList<Text> &alsoList) alternateName = "set"; alternateName += func->name()[0].toUpper(); alternateName += func->name().mid(1); - alternateFunc = func->parent()->findFunctionNode(alternateName); + alternateFunc = func->parent()->findFunctionNode(alternateName, QString()); } if (alternateFunc && alternateFunc->access() != Node::Private) { diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp index 8646e699a9..1ed6820fbf 100644 --- a/src/tools/qdoc/node.cpp +++ b/src/tools/qdoc/node.cpp @@ -34,11 +34,12 @@ #include "node.h" #include "tree.h" #include "codemarker.h" -#include "codeparser.h" +#include "cppcodeparser.h" #include <quuid.h> #include "qdocdatabase.h" #include <qdebug.h> #include "generator.h" +#include "tokenizer.h" QT_BEGIN_NAMESPACE @@ -810,9 +811,56 @@ Node* Aggregate::findChildNode(const QString& name, NodeType type) Find a function node that is a child of this nose, such that the function node has the specified \a name. */ -FunctionNode *Aggregate::findFunctionNode(const QString& name) const -{ - return static_cast<FunctionNode *>(primaryFunctionMap_.value(name)); +FunctionNode *Aggregate::findFunctionNode(const QString& name, const QString& params) const +{ + FunctionNode* pfn = static_cast<FunctionNode*>(primaryFunctionMap_.value(name)); + FunctionNode* fn = pfn; + if (fn) { + const QVector<Parameter>* funcParams = &(fn->parameters()); + if (params.isEmpty() && funcParams->isEmpty()) + return fn; + bool isQPrivateSignal = false; // Not used in the search + QVector<Parameter> testParams; + if (!params.isEmpty()) { + CppCodeParser* cppParser = CppCodeParser::cppParser(); + cppParser->parseParameters(params, testParams, isQPrivateSignal); + } + NodeList funcs = secondaryFunctionMap_.value(name); + int i = -1; + while (fn) { + if (testParams.size() == funcParams->size()) { + if (testParams.isEmpty()) + return fn; + bool different = false; + for (int j=0; j<testParams.size(); j++) { + if (testParams.at(j).dataType() != funcParams->at(j).dataType()) { + different = true; + break; + } + } + if (!different) + return fn; + } + if (++i < funcs.size()) { + fn = static_cast<FunctionNode*>(funcs.at(i)); + funcParams = &(fn->parameters()); + } + else + fn = 0; + } + if (!fn && !testParams.empty()) + return 0; + } + /* + Most \l commands that link to functions don't include + the parameter declarations in the function signature, + so if the \l is meant to go to a function that does + have parameters, the algorithm above won't find it. + Therefore we must return the pointer to the function + in the primary function map in the cases where the + parameters should have been specified in the \l command. + */ + return (fn ? fn : pfn); } /*! @@ -1090,20 +1138,20 @@ void Aggregate::setIncludes(const QStringList& includes) */ bool Aggregate::isSameSignature(const FunctionNode *f1, const FunctionNode *f2) { - if (f1->parameters().count() != f2->parameters().count()) + if (f1->parameters().size() != f2->parameters().size()) return false; if (f1->isConst() != f2->isConst()) return false; - QList<Parameter>::ConstIterator p1 = f1->parameters().constBegin(); - QList<Parameter>::ConstIterator p2 = f2->parameters().constBegin(); + QVector<Parameter>::ConstIterator p1 = f1->parameters().constBegin(); + QVector<Parameter>::ConstIterator p2 = f2->parameters().constBegin(); while (p2 != f2->parameters().constEnd()) { if ((*p1).hasType() && (*p2).hasType()) { if ((*p1).rightType() != (*p2).rightType()) return false; - QString t1 = p1->leftType(); - QString t2 = p2->leftType(); + QString t1 = p1->dataType(); + QString t2 = p2->dataType(); if (t1.length() < t2.length()) qSwap(t1, t2); @@ -1751,33 +1799,40 @@ void TypedefNode::setAssociatedEnum(const EnumNode *enume) /*! Constructs this parameter from the left and right types - \a leftType and rightType, the parameter \a name, and the + \a dataType and rightType, the parameter \a name, and the \a defaultValue. In practice, \a rightType is not used, and I don't know what is was meant for. */ -Parameter::Parameter(const QString& leftType, +Parameter::Parameter(const QString& dataType, const QString& rightType, const QString& name, const QString& defaultValue) - : leftType_(leftType), rightType_(rightType), name_(name), defaultValue_(defaultValue) + : dataType_(dataType), + rightType_(rightType), + name_(name), + defaultValue_(defaultValue) { + // nothing. } /*! - The standard copy constructor copies the strings from \a p. + Standard copy constructor copies \p. */ Parameter::Parameter(const Parameter& p) - : leftType_(p.leftType_), rightType_(p.rightType_), name_(p.name_), defaultValue_(p.defaultValue_) + : dataType_(p.dataType_), + rightType_(p.rightType_), + name_(p.name_), + defaultValue_(p.defaultValue_) { + // nothing. } /*! - Assigning Parameter \a p to this Parameter copies the - strings across. + standard assignment operator assigns \p. */ Parameter& Parameter::operator=(const Parameter& p) { - leftType_ = p.leftType_; + dataType_ = p.dataType_; rightType_ = p.rightType_; name_ = p.name_; defaultValue_ = p.defaultValue_; @@ -1791,7 +1846,7 @@ Parameter& Parameter::operator=(const Parameter& p) */ QString Parameter::reconstruct(bool value) const { - QString p = leftType_ + rightType_; + QString p = dataType_ + rightType_; if (!p.endsWith(QChar('*')) && !p.endsWith(QChar('&')) && !p.endsWith(QChar(' '))) p += QLatin1Char(' '); p += name_; @@ -1902,8 +1957,8 @@ void FunctionNode::addParameter(const Parameter& parameter) */ void FunctionNode::borrowParameterNames(const FunctionNode *source) { - QList<Parameter>::Iterator t = parameters_.begin(); - QList<Parameter>::ConstIterator s = source->parameters_.constBegin(); + QVector<Parameter>::Iterator t = parameters_.begin(); + QVector<Parameter>::ConstIterator s = source->parameters_.constBegin(); while (s != source->parameters_.constEnd() && t != parameters_.end()) { if (!(*s).name().isEmpty()) (*t).setName((*s).name()); @@ -1958,7 +2013,7 @@ bool FunctionNode::hasActiveAssociatedProperty() const QStringList FunctionNode::parameterNames() const { QStringList names; - QList<Parameter>::ConstIterator p = parameters().constBegin(); + QVector<Parameter>::ConstIterator p = parameters().constBegin(); while (p != parameters().constEnd()) { names << (*p).name(); ++p; @@ -1975,7 +2030,7 @@ QString FunctionNode::rawParameters(bool names, bool values) const { QString raw; foreach (const Parameter ¶meter, parameters()) { - raw += parameter.leftType() + parameter.rightType(); + raw += parameter.dataType() + parameter.rightType(); if (names) raw += parameter.name(); if (values) @@ -1991,7 +2046,7 @@ QString FunctionNode::rawParameters(bool names, bool values) const QStringList FunctionNode::reconstructParameters(bool values) const { QStringList reconstructedParameters; - QList<Parameter>::ConstIterator p = parameters().constBegin(); + QVector<Parameter>::ConstIterator p = parameters().constBegin(); while (p != parameters().constEnd()) { reconstructedParameters << (*p).reconstruct(values); ++p; diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h index e9816dad19..596a71b6d5 100644 --- a/src/tools/qdoc/node.h +++ b/src/tools/qdoc/node.h @@ -376,7 +376,7 @@ public: Node* findChildNode(const QString& name, Node::Genus genus) const; Node* findChildNode(const QString& name, NodeType type); virtual void findChildren(const QString& name, NodeList& nodes) const Q_DECL_OVERRIDE; - FunctionNode* findFunctionNode(const QString& name) const; + FunctionNode* findFunctionNode(const QString& name, const QString& params) const; FunctionNode* findFunctionNode(const FunctionNode* clone) const; void addInclude(const QString &include); void setIncludes(const QStringList &includes); @@ -815,12 +815,11 @@ inline void EnumNode::setFlagsType(TypedefNode* t) t->setAssociatedEnum(this); } - class Parameter { public: Parameter() {} - Parameter(const QString& leftType, + Parameter(const QString& dataType, const QString& rightType = QString(), const QString& name = QString(), const QString& defaultValue = QString()); @@ -830,21 +829,24 @@ public: void setName(const QString& name) { name_ = name; } - bool hasType() const { return leftType_.length() + rightType_.length() > 0; } - const QString& leftType() const { return leftType_; } + bool hasType() const { return dataType_.length() + rightType_.length() > 0; } + const QString& dataType() const { return dataType_; } const QString& rightType() const { return rightType_; } const QString& name() const { return name_; } const QString& defaultValue() const { return defaultValue_; } QString reconstruct(bool value = false) const; -private: - QString leftType_; - QString rightType_; + public: + QString dataType_; + QString rightType_; // mws says remove this 04/08/2015 QString name_; QString defaultValue_; }; +//friend class QTypeInfo<Parameter>; +//Q_DECLARE_TYPEINFO(Parameter, Q_MOVABLE_TYPE); + class FunctionNode : public LeafNode { public: @@ -874,7 +876,7 @@ public: void setOverloadNumber(unsigned char n) { overloadNumber_ = n; } void setReimplemented(bool b); void addParameter(const Parameter& parameter); - inline void setParameters(const QList<Parameter>& parameters); + inline void setParameters(const QVector<Parameter>& parameters); void borrowParameterNames(const FunctionNode* source); void setReimplementedFrom(FunctionNode* from); @@ -907,7 +909,7 @@ public: virtual bool isJsMethod() const Q_DECL_OVERRIDE { return (type() == Node::QmlMethod) && (genus() == Node::JS); } - const QList<Parameter>& parameters() const { return parameters_; } + const QVector<Parameter>& parameters() const { return parameters_; } void clearParams() { parameters_.clear(); } QStringList parameterNames() const; QString rawParameters(bool names = false, bool values = false) const; @@ -957,7 +959,7 @@ private: bool privateSignal_: 1; bool overload_ : 1; unsigned char overloadNumber_; - QList<Parameter> parameters_; + QVector<Parameter> parameters_; const FunctionNode* reimplementedFrom_; PropNodeList associatedProperties_; QList<FunctionNode*> reimplementedBy_; @@ -1030,7 +1032,7 @@ private: const PropertyNode* overrides_; }; -inline void FunctionNode::setParameters(const QList<Parameter> &p) +inline void FunctionNode::setParameters(const QVector<Parameter> &p) { parameters_ = p; } diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp index 5f2a61bb76..7f2e64b00c 100644 --- a/src/tools/qdoc/qdocdatabase.cpp +++ b/src/tools/qdoc/qdocdatabase.cpp @@ -380,6 +380,30 @@ QString QDocForest::getLinkCounts(QStringList& strings, QVector<int>& counts) return depends; } +/*! + */ +const Node* QDocForest::findFunctionNode(const QString& target, + const Node* relative, + Node::Genus genus) +{ + QString function, params; + int length = target.length(); + if (target.endsWith(QChar(')'))) { + int position = target.lastIndexOf(QChar('(')); + params = target.mid(position+1, length-position-2); + function = target.left(position); + } + else + function = target; + foreach (Tree* t, searchOrder()) { + const Node* n = t->findFunctionNode(function, params, relative, genus); + if (n) + return n; + relative = 0; + } + return 0; +} + /*! \class QDocDatabase This class provides exclusive access to the qdoc database, which consists of a forrest of trees and a lot of maps and @@ -1342,8 +1366,16 @@ void QDocDatabase::resolveNamespaces() } } } - - +#if 0 +/*! + */ +const Node* QDocDatabase::findFunctionNode(const QString& target, + const Node* relative, + Node::Genus genus) +{ + return forest_.findFunctionNode(target, relative, genus); +} +#endif /*! This function is called for autolinking to a \a type, which could be a function return type or a parameter @@ -1641,6 +1673,8 @@ const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, Q Atom* atom = const_cast<Atom*>(a); QStringList targetPath = atom->string().split("#"); QString first = targetPath.first().trimmed(); + if (Generator::debugging()) + qDebug() << " first:" << first; Tree* domain = 0; Node::Genus genus = Node::DontCare; @@ -1659,8 +1693,14 @@ const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, Q else if (domain) { if (first.endsWith(".html")) node = domain->findNodeByNameAndType(QStringList(first), Node::Document); - else if (first.endsWith("()")) - node = domain->findFunctionNode(first, 0, genus); + else if (first.endsWith(QChar(')'))) { + QString function, params; + int length = first.length(); + int position = first.lastIndexOf(QChar('(')); + params = first.mid(position+1, length-position-2); + function = first.left(position); + node = domain->findFunctionNode(function, params, 0, genus); + } else { int flags = SearchBaseClasses | SearchEnumValues; QStringList nodePath = first.split("::"); @@ -1683,8 +1723,11 @@ const Node* QDocDatabase::findNodeForAtom(const Atom* a, const Node* relative, Q if (!node && first.contains("/")) return findNodeForTarget(targetPath, relative, genus, ref); } - else if (first.endsWith("()")) + else if (first.endsWith(QChar(')'))) { node = findFunctionNode(first, relative, genus); + if (Generator::debugging()) + qDebug() << " node:" << node; + } else { node = findNodeForTarget(targetPath, relative, genus, ref); return node; diff --git a/src/tools/qdoc/qdocdatabase.h b/src/tools/qdoc/qdocdatabase.h index 5d55ea48e1..80a92af4ed 100644 --- a/src/tools/qdoc/qdocdatabase.h +++ b/src/tools/qdoc/qdocdatabase.h @@ -141,15 +141,8 @@ class QDocForest const Node* findFunctionNode(const QString& target, const Node* relative, - Node::Genus genus) { - foreach (Tree* t, searchOrder()) { - const Node* n = t->findFunctionNode(target, relative, genus); - if (n) - return n; - relative = 0; - } - return 0; - } + Node::Genus genus); + const Node* findNodeForTarget(QStringList& targetPath, const Node* relative, Node::Genus genus, diff --git a/src/tools/qdoc/qdocindexfiles.cpp b/src/tools/qdoc/qdocindexfiles.cpp index 37194b911c..8db901bbc7 100644 --- a/src/tools/qdoc/qdocindexfiles.cpp +++ b/src/tools/qdoc/qdocindexfiles.cpp @@ -1238,7 +1238,7 @@ bool QDocIndexFiles::generateIndexSection(QXmlStreamWriter& writer, for (int i = 0; i < functionNode->parameters().size(); ++i) { Parameter parameter = functionNode->parameters()[i]; writer.writeStartElement("parameter"); - writer.writeAttribute("left", parameter.leftType()); + writer.writeAttribute("left", parameter.dataType()); writer.writeAttribute("right", parameter.rightType()); writer.writeAttribute("name", parameter.name()); writer.writeAttribute("default", parameter.defaultValue()); diff --git a/src/tools/qdoc/qmlvisitor.cpp b/src/tools/qdoc/qmlvisitor.cpp index 6f63624bf0..155e1de054 100644 --- a/src/tools/qdoc/qmlvisitor.cpp +++ b/src/tools/qdoc/qmlvisitor.cpp @@ -675,7 +675,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::UiPublicMember *member) QString name = member->name.toString(); FunctionNode *qmlSignal = new FunctionNode(Node::QmlSignal, current, name, false); - QList<Parameter> parameters; + QVector<Parameter> parameters; for (QQmlJS::AST::UiParameterList *it = member->parameters; it; it = it->next) { if (!it->type.isEmpty() && !it->name.isEmpty()) parameters.append(Parameter(it->type.toString(), QString(), it->name.toString())); @@ -754,7 +754,7 @@ bool QmlDocVisitor::visit(QQmlJS::AST::FunctionDeclaration* fd) } if (overloads > 1) qmlMethod->setOverloadFlag(true); - QList<Parameter> parameters; + QVector<Parameter> parameters; QQmlJS::AST::FormalParameterList* formals = fd->formals; if (formals) { QQmlJS::AST::FormalParameterList* fpl = formals; diff --git a/src/tools/qdoc/tokenizer.cpp b/src/tools/qdoc/tokenizer.cpp index a85c3b00d8..987fff548c 100644 --- a/src/tools/qdoc/tokenizer.cpp +++ b/src/tools/qdoc/tokenizer.cpp @@ -33,6 +33,7 @@ #include "config.h" #include "tokenizer.h" +#include "generator.h" #include <qfile.h> #include <qhash.h> diff --git a/src/tools/qdoc/tree.cpp b/src/tools/qdoc/tree.cpp index e0fd68d2e7..d64903e61e 100644 --- a/src/tools/qdoc/tree.cpp +++ b/src/tools/qdoc/tree.cpp @@ -220,6 +220,7 @@ QmlTypeNode* Tree::findQmlTypeNode(const QStringList& path) used as the starting point. */ const FunctionNode* Tree::findFunctionNode(const QStringList& path, + const QString& params, const Node* relative, int findFlags, Node::Genus genus) const @@ -234,7 +235,7 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path, qcn = static_cast<QmlTypeNode*>(n); } if (qcn) - return static_cast<const FunctionNode*>(qcn->findFunctionNode(path[2])); + return static_cast<const FunctionNode*>(qcn->findFunctionNode(path[2], params)); } if (!relative) @@ -254,7 +255,7 @@ const FunctionNode* Tree::findFunctionNode(const QStringList& path, const Node* next; if (i == path.size() - 1) - next = ((const Aggregate*) node)->findFunctionNode(path.at(i)); + next = ((const Aggregate*) node)->findFunctionNode(path.at(i), params); else next = ((const Aggregate*) node)->findChildNode(path.at(i), genus); @@ -262,7 +263,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 Aggregate*>(baseClass)->findFunctionNode(path.at(i)); + next = static_cast<const Aggregate*>(baseClass)->findFunctionNode(path.at(i), params); else next = static_cast<const Aggregate*>(baseClass)->findChildNode(path.at(i), genus); @@ -1452,13 +1453,17 @@ void Tree::insertQmlType(const QString& key, QmlTypeNode* n) Split \a target on "::" and find the function node with that path. */ -const Node* Tree::findFunctionNode(const QString& target, const Node* relative, Node::Genus genus) +const Node* Tree::findFunctionNode(const QString& target, + const QString& params, + const Node* relative, + Node::Genus genus) const { QString t = target; - if (t.endsWith("()")) + if (t.endsWith("()")) { t.chop(2); + } QStringList path = t.split("::"); - const FunctionNode* fn = findFunctionNode(path, relative, SearchBaseClasses, genus); + const FunctionNode* fn = findFunctionNode(path, params, relative, SearchBaseClasses, genus); if (fn && fn->metaness() != FunctionNode::MacroWithoutParams) return fn; return 0; diff --git a/src/tools/qdoc/tree.h b/src/tools/qdoc/tree.h index 9e195c90ae..1fef15bc6d 100644 --- a/src/tools/qdoc/tree.h +++ b/src/tools/qdoc/tree.h @@ -107,7 +107,10 @@ class Tree ClassNode* findClassNode(const QStringList& path, const Node* start = 0) const; NamespaceNode* findNamespaceNode(const QStringList& path) const; FunctionNode* findFunctionNode(const QStringList& parentPath, const FunctionNode* clone); - const Node* findFunctionNode(const QString& target, const Node* relative, Node::Genus genus); + const Node* findFunctionNode(const QString& target, + const QString& params, + const Node* relative, + Node::Genus genus) const; Node* findNodeRecursive(const QStringList& path, int pathIndex, @@ -163,6 +166,7 @@ class Tree NamespaceNode *root() { return &root_; } const FunctionNode *findFunctionNode(const QStringList &path, + const QString& params, const Node *relative = 0, int findFlags = 0, Node::Genus genus = Node::DontCare) const; |