diff options
Diffstat (limited to 'src/tools/qdoc/cppcodeparser.cpp')
-rw-r--r-- | src/tools/qdoc/cppcodeparser.cpp | 472 |
1 files changed, 296 insertions, 176 deletions
diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp index f12fb70227..5d2a2c90d0 100644 --- a/src/tools/qdoc/cppcodeparser.cpp +++ b/src/tools/qdoc/cppcodeparser.cpp @@ -51,8 +51,10 @@ QT_BEGIN_NAMESPACE /* qmake ignore Q_OBJECT */ static bool inMacroCommand_ = false; +static bool parsingHeaderFile_ = false; QStringList CppCodeParser::exampleFiles; QStringList CppCodeParser::exampleDirs; +CppCodeParser* CppCodeParser::cppParser_ = 0; /*! The constructor initializes some regular expressions @@ -62,6 +64,7 @@ CppCodeParser::CppCodeParser() : varComment("/\\*\\s*([a-zA-Z_0-9]+)\\s*\\*/"), sep("(?:<[^>]+>)?::") { reset(); + cppParser_ = this; } /*! @@ -166,7 +169,9 @@ void CppCodeParser::parseHeaderFile(const Location& location, const QString& fil Tokenizer fileTokenizer(fileLocation, in); tokenizer = &fileTokenizer; readToken(); + parsingHeaderFile_ = true; matchDeclList(qdb_->primaryTreeRoot()); + parsingHeaderFile_ = false; if (!fileTokenizer.version().isEmpty()) qdb_->setVersion(fileTokenizer.version()); in.close(); @@ -250,16 +255,11 @@ void CppCodeParser::doneParsingHeaderFiles() /*! This is called after all the source files (i.e., not the - header files) have been parsed. It traverses the tree to - resolve property links, normalize overload signatures, and - do other housekeeping of the database. + header files) have been parsed. Currently nothing to do. */ void CppCodeParser::doneParsingSourceFiles() { - qdb_->primaryTreeRoot()->normalizeOverloads(); - qdb_->fixInheritance(); - qdb_->resolveProperties(); - qdb_->primaryTreeRoot()->makeUndocumentedChildrenInternal(); + // contents moved to QdocDatabase::resolveIssues() } static QSet<QString> topicCommands_; @@ -376,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); } @@ -408,7 +408,7 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, this way to allow the writer to refer to the entity without including the namespace qualifier. */ - Node::Type type = nodeTypeMap[command]; + Node::NodeType type = nodeTypeMap[command]; QStringList paths = arg.first.split(QLatin1Char(' ')); QStringList path = paths[0].split("::"); Node *node = 0; @@ -422,7 +422,7 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, lastPath_ = path; } - else if (node->isInnerNode()) { + else if (node->isAggregate()) { if (type == Node::Namespace) { NamespaceNode* ns = static_cast<NamespaceNode*>(node); ns->markSeen(); @@ -520,16 +520,6 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, else if (t == "ditamap") ptype = Node::DitaMapPage; } - -#if 0 - const Node* n = qdb_->checkForCollision(args[0]); - if (n) { - QString other = n->doc().location().fileName(); - doc.location().warning(tr("Name/title collision detected: '%1' in '\\%2'") - .arg(args[0]).arg(command), - tr("Also used here: %1").arg(other)); - } -#endif DocumentNode* dn = 0; if (ptype == Node::DitaMapPage) dn = new DitaMapNode(qdb_->primaryTreeRoot(), args[0]); @@ -572,7 +562,7 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, QmlTypeNode* qmlType = qdb_->findQmlType(module, qmlTypeName); if (qmlType) { bool attached = false; - Node::Type nodeType = Node::QmlMethod; + Node::NodeType nodeType = Node::QmlMethod; if ((command == COMMAND_QMLSIGNAL) || (command == COMMAND_JSSIGNAL)) nodeType = Node::QmlSignal; @@ -697,10 +687,10 @@ bool CppCodeParser::splitQmlPropertyArg(const QString& arg, <type> <QML-type>::<name>(<param>, <param>, ...) <type> <QML-module>::<QML-type>::<name>(<param>, <param>, ...) - This function splits the argument into one of those two - forms, sets \a module, \a qmlTypeName, and \a name, and returns - true. If the argument doesn't match either form, an error - message is emitted and false is returned. + This function splits the \a{arg}ument into one of those + two forms, sets \a type, \a module, and \a qmlTypeName, + and returns true. If the argument doesn't match either + form, an error message is emitted and false is returned. \note The two QML types \e{Component} and \e{QtObject} never have a module qualifier. @@ -710,30 +700,29 @@ bool CppCodeParser::splitQmlMethodArg(const QString& arg, QString& module, QString& qmlTypeName) { - QStringList colonSplit(arg.split("::")); + QString name; + int leftParen = arg.indexOf(QChar('(')); + if (leftParen > 0) + name = arg.left(leftParen); + else + name = arg; + int firstBlank = name.indexOf(QChar(' ')); + if (firstBlank > 0) { + type = name.left(firstBlank); + name = name.right(name.length() - firstBlank - 1); + } + else + type.clear(); + + QStringList colonSplit(name.split("::")); if (colonSplit.size() > 1) { - QStringList blankSplit = colonSplit[0].split(QLatin1Char(' ')); - if (blankSplit.size() > 1) { - type = blankSplit[0]; - if (colonSplit.size() > 2) { - module = blankSplit[1]; - qmlTypeName = colonSplit[1]; - } - else { - module.clear(); - qmlTypeName = blankSplit[1]; - } + if (colonSplit.size() > 2) { + module = colonSplit[0]; + qmlTypeName = colonSplit[1]; } else { - type.clear(); - if (colonSplit.size() > 2) { - module = colonSplit[0]; - qmlTypeName = colonSplit[1]; - } - else { - module.clear(); - qmlTypeName = colonSplit[0]; - } + module.clear(); + qmlTypeName = colonSplit[0]; } return true; } @@ -870,7 +859,8 @@ const QSet<QString>& CppCodeParser::otherMetaCommands() << COMMAND_QMLINSTANTIATES << COMMAND_QMLDEFAULT << COMMAND_QMLREADONLY - << COMMAND_QMLABSTRACT; + << COMMAND_QMLABSTRACT + << COMMAND_ABSTRACT; } return otherMetaCommands_; } @@ -887,22 +877,18 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, { QString arg = argLocPair.first; if (command == COMMAND_INHEADERFILE) { - if (node != 0 && node->isInnerNode()) { - ((InnerNode *) node)->addInclude(arg); + if (node != 0 && node->isAggregate()) { + ((Aggregate *) node)->addInclude(arg); } else { - doc.location().warning(tr("Ignored '\\%1'") - .arg(COMMAND_INHEADERFILE)); + doc.location().warning(tr("Ignored '\\%1'").arg(COMMAND_INHEADERFILE)); } } else if (command == COMMAND_OVERLOAD) { - if (node != 0 && node->type() == Node::Function) { - ((FunctionNode *) node)->setOverload(true); - } - else { - doc.location().warning(tr("Ignored '\\%1'") - .arg(COMMAND_OVERLOAD)); - } + if (node && node->isFunction()) + ((FunctionNode *) node)->setOverloadFlag(true); + else + doc.location().warning(tr("Ignored '\\%1'").arg(COMMAND_OVERLOAD)); } else if (command == COMMAND_REIMP) { if (node != 0 && node->parent() && !node->parent()->isInternal()) { @@ -928,22 +914,29 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, "because its base function is private " "or internal").arg(COMMAND_REIMP).arg(node->name())); } - func->setReimp(true); + func->setReimplemented(true); } else { - doc.location().warning(tr("Ignored '\\%1' in %2") - .arg(COMMAND_REIMP) - .arg(node->name())); + doc.location().warning(tr("Ignored '\\%1' in %2").arg(COMMAND_REIMP).arg(node->name())); } } } else if (command == COMMAND_RELATES) { QStringList path = arg.split("::"); Node* n = qdb_->findRelatesNode(path); - if (!n) - doc.location().warning(tr("Cannot find '%1' in '\\%2'").arg(arg).arg(COMMAND_RELATES)); + if (!n) { + // Store just a string to write to the index file + if (Generator::preparing()) + node->setRelates(arg); + else + doc.location().warning(tr("Cannot find '%1' in '\\%2'").arg(arg).arg(COMMAND_RELATES)); + + } + else if (node->parent() != n) + node->setRelates(static_cast<Aggregate*>(n)); else - node->setRelates(static_cast<InnerNode*>(n)); + doc.location().warning(tr("Invalid use of '\\%1' (already a member of '%2')") + .arg(COMMAND_RELATES, arg)); } else if (command == COMMAND_CONTENTSPAGE) { setLink(node, Node::ContentsLink, arg); @@ -1014,7 +1007,7 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, } } } - else if (command == COMMAND_QMLABSTRACT) { + else if ((command == COMMAND_QMLABSTRACT) || (command == COMMAND_ABSTRACT)) { if (node->isQmlType() || node->isJsType()) node->setAbstract(true); } @@ -1051,7 +1044,7 @@ void CppCodeParser::reset() tokenizer = 0; tok = 0; access = Node::Public; - metaness = FunctionNode::Plain; + metaness_ = FunctionNode::Plain; lastPath_.clear(); physicalModuleName.clear(); } @@ -1096,8 +1089,7 @@ bool CppCodeParser::match(int target) readToken(); return true; } - else - return false; + return false; } /*! @@ -1236,8 +1228,9 @@ bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var) dataType->append(previousLexeme()); } else if (match(Tok_void) || match(Tok_int) || match(Tok_char) || - match(Tok_double) || match(Tok_Ellipsis)) + match(Tok_double) || match(Tok_Ellipsis)) { dataType->append(previousLexeme()); + } else { return false; } @@ -1323,37 +1316,72 @@ bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var) return true; } -bool CppCodeParser::matchParameter(FunctionNode *func) +/*! + Parse the next function parameter, if there is one, and + 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(QVector<Parameter>& pvect, bool& isQPrivateSignal) { - CodeChunk dataType; - QString name; - CodeChunk defaultValue; - if (match(Tok_QPrivateSignal)) { - func->setPrivateSignal(); + isQPrivateSignal = true; return true; } - if (!matchDataType(&dataType, &name)) { + Parameter p; + CodeChunk chunk; + if (!matchDataType(&chunk, &p.name_)) { return false; } + p.dataType_ = chunk.toString(); + chunk.clear(); match(Tok_Comment); if (match(Tok_Equal)) { - int parenDepth0 = tokenizer->parenDepth(); - - while (tokenizer->parenDepth() >= parenDepth0 && - (tok != Tok_Comma || - tokenizer->parenDepth() > parenDepth0) && + int pdepth = tokenizer->parenDepth(); + while (tokenizer->parenDepth() >= pdepth && + (tok != Tok_Comma || (tokenizer->parenDepth() > pdepth)) && tok != Tok_Eoi) { - defaultValue.append(lexeme()); + chunk.append(lexeme()); readToken(); } } - func->addParameter(Parameter(dataType.toString(), "", name, defaultValue.toString())); // ### + p.defaultValue_ = chunk.toString(); + pvect.append(p); return true; } -bool CppCodeParser::matchFunctionDecl(InnerNode *parent, +/*! + If the current token is any of several function modifiers, + return that token value after reading the next token. If it + is not one of the function modieifer tokens, return -1 but + don\t read the next token. + */ +int CppCodeParser::matchFunctionModifier() +{ + switch (tok) { + case Tok_friend: + case Tok_inline: + case Tok_explicit: + case Tok_static: + case Tok_QT_DEPRECATED: + readToken(); + return tok; + case Tok_QT_COMPAT: + case Tok_QT_COMPAT_CONSTRUCTOR: + case Tok_QT_MOC_COMPAT: + case Tok_QT3_SUPPORT: + case Tok_QT3_SUPPORT_CONSTRUCTOR: + case Tok_QT3_MOC_SUPPORT: + readToken(); + return Tok_QT_COMPAT; + default: + break; + } + return -1; +} + +bool CppCodeParser::matchFunctionDecl(Aggregate *parent, QStringList *parentPathPtr, FunctionNode **funcPtr, const QString &templateStuff, @@ -1362,25 +1390,44 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, CodeChunk returnType; QStringList parentPath; QString name; - bool compat = false; - if (match(Tok_friend)) { - return false; - } - match(Tok_explicit); - if (matchCompat()) - compat = true; - bool sta = false; - if (match(Tok_static)) { - sta = true; - if (matchCompat()) - compat = true; + bool matched_QT_DEPRECATED = false; + bool matched_friend = false; + bool matched_static = false; + bool matched_inline = false; + bool matched_explicit = false; + bool matched_compat = false; + + int token = tok; + while (token != -1) { + switch (token) { + case Tok_friend: + matched_friend = true; + break; + case Tok_inline: + matched_inline = true; + break; + case Tok_explicit: + matched_explicit = true; + break; + case Tok_static: + matched_static = true; + break; + case Tok_QT_DEPRECATED: + // no break here. + matched_QT_DEPRECATED = true; + case Tok_QT_COMPAT: + matched_compat = true; + break; + } + token = matchFunctionModifier(); } - FunctionNode::Virtualness vir = FunctionNode::NonVirtual; + + FunctionNode::Virtualness virtuality = FunctionNode::NonVirtual; if (match(Tok_virtual)) { - vir = FunctionNode::ImpureVirtual; - if (matchCompat()) - compat = true; + virtuality = FunctionNode::NormalVirtual; + if (!matched_compat) + matched_compat = matchCompat(); } if (!matchDataType(&returnType)) { @@ -1397,8 +1444,8 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, if (returnType.toString() == "QBool") returnType = CodeChunk("bool"); - if (matchCompat()) - compat = true; + if (!matched_compat) + matched_compat = matchCompat(); if (tok == Tok_operator && (returnType.toString().isEmpty() || @@ -1437,12 +1484,10 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, else { while (match(Tok_Ident)) { name = previousLexeme(); - /* This is a hack to let QML module identifiers through. */ matchModuleQualifier(name); - matchTemplateAngles(); if (match(Tok_Gulbrandsen)) @@ -1496,68 +1541,111 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, var->setLocation(location()); var->setLeftType(returnType.left()); var->setRightType(returnType.right()); - if (compat) + if (matched_compat) var->setStatus(Node::Compat); - var->setStatic(sta); + var->setStatic(matched_static); return false; } - if (tok != Tok_LeftParen) { + if (tok != Tok_LeftParen) return false; - } } readToken(); - FunctionNode *func = new FunctionNode(extra.type, parent, name, extra.isAttached); - func->setAccess(access); - func->setLocation(location()); - func->setReturnType(returnType.toString()); - func->setParentPath(parentPath); - func->setTemplateStuff(templateStuff); - if (compat) - func->setStatus(Node::Compat); - - func->setMetaness(metaness); - if (parent) { - if (name == parent->name()) { - func->setMetaness(FunctionNode::Ctor); - } else if (name.startsWith(QLatin1Char('~'))) { - func->setMetaness(FunctionNode::Dtor); - } - } - func->setStatic(sta); - + // A left paren was seen. Parse the parameters + bool isQPrivateSignal = false; + QVector<Parameter> pvect; if (tok != Tok_RightParen) { do { - if (!matchParameter(func)) { + if (!matchParameter(pvect, isQPrivateSignal)) return false; - } } while (match(Tok_Comma)); } - if (!match(Tok_RightParen)) { + // The parameters must end with a right paren + if (!match(Tok_RightParen)) return false; - } - func->setConst(match(Tok_const)); + // look for const + bool matchedConst = match(Tok_const); + // look for 0 indicating pure virtual if (match(Tok_Equal) && match(Tok_Number)) - vir = FunctionNode::PureVirtual; - func->setVirtualness(vir); + virtuality = FunctionNode::PureVirtual; + // look for colon indicating ctors which must be skipped if (match(Tok_Colon)) { while (tok != Tok_LeftBrace && tok != Tok_Eoi) readToken(); } + // If no ';' expect a body, which must be skipped. + bool body_expected = false; + bool body_present = false; if (!match(Tok_Semicolon) && tok != Tok_Eoi) { - int braceDepth0 = tokenizer->braceDepth(); - - if (!match(Tok_LeftBrace)) { + body_expected = true; + int nesting = tokenizer->braceDepth(); + if (!match(Tok_LeftBrace)) return false; - } - while (tokenizer->braceDepth() >= braceDepth0 && tok != Tok_Eoi) + // skip the body + while (tokenizer->braceDepth() >= nesting && tok != Tok_Eoi) readToken(); + body_present = true; match(Tok_RightBrace); } + + FunctionNode *func = 0; + bool createFunctionNode = false; + if (parsingHeaderFile_) { + if (matched_friend) { + if (matched_inline) { + // nothing yet + } + if (body_present) { + if (body_expected) { + // nothing yet + } + createFunctionNode = true; + if (parent && parent->parent()) + parent = parent->parent(); + else + return false; + } + } + else + createFunctionNode = true; + } + else + createFunctionNode = true; + + if (createFunctionNode) { + func = new FunctionNode(extra.type, parent, name, extra.isAttached); + if (matched_friend) + access = Node::Public; + func->setAccess(access); + func->setLocation(location()); + func->setReturnType(returnType.toString()); + func->setParentPath(parentPath); + func->setTemplateStuff(templateStuff); + if (matched_compat) + func->setStatus(Node::Compat); + if (matched_QT_DEPRECATED) + func->setStatus(Node::Deprecated); + if (matched_explicit) { /* What can be done? */ } + func->setMetaness(metaness_); + if (parent) { + if (name == parent->name()) + func->setMetaness(FunctionNode::Ctor); + else if (name.startsWith(QLatin1Char('~'))) + func->setMetaness(FunctionNode::Dtor); + } + func->setStatic(matched_static); + func->setConst(matchedConst); + func->setVirtualness(virtuality); + if (isQPrivateSignal) + func->setPrivateSignal(); + if (!pvect.isEmpty()) { + func->setParameters(pvect); + } + } if (parentPathPtr != 0) *parentPathPtr = parentPath; if (funcPtr != 0) @@ -1616,7 +1704,7 @@ bool CppCodeParser::matchBaseList(ClassNode *classe, bool isClass) sufficient for Qt because there are no cases of class nesting more than one level deep. */ -bool CppCodeParser::matchClassDecl(InnerNode *parent, +bool CppCodeParser::matchClassDecl(Aggregate *parent, const QString &templateStuff) { bool isClass = (tok == Tok_class); @@ -1631,7 +1719,7 @@ bool CppCodeParser::matchClassDecl(InnerNode *parent, if (tok == Tok_Gulbrandsen) { Node* n = parent->findChildNode(previousLexeme(),Node::Class); if (n) { - parent = static_cast<InnerNode*>(n); + parent = static_cast<Aggregate*>(n); if (parent) { readToken(); if (tok != Tok_Ident) @@ -1663,17 +1751,17 @@ bool CppCodeParser::matchClassDecl(InnerNode *parent, Node::Access outerAccess = access; access = isClass ? Node::Private : Node::Public; - FunctionNode::Metaness outerMetaness = metaness; - metaness = FunctionNode::Plain; + FunctionNode::Metaness outerMetaness = metaness_; + metaness_ = FunctionNode::Plain; bool matches = (matchDeclList(classe) && match(Tok_RightBrace) && match(Tok_Semicolon)); access = outerAccess; - metaness = outerMetaness; + metaness_ = outerMetaness; return matches; } -bool CppCodeParser::matchNamespaceDecl(InnerNode *parent) +bool CppCodeParser::matchNamespaceDecl(Aggregate *parent) { readToken(); // skip 'namespace' if (tok != Tok_Ident) @@ -1712,7 +1800,7 @@ bool CppCodeParser::matchNamespaceDecl(InnerNode *parent) member function is added to \a parent as an unresolved \c using clause. */ -bool CppCodeParser::matchUsingDecl(InnerNode* parent) +bool CppCodeParser::matchUsingDecl(Aggregate* parent) { bool usingNamespace = false; readToken(); // skip 'using' @@ -1774,17 +1862,25 @@ bool CppCodeParser::matchUsingDecl(InnerNode* parent) return true; } -bool CppCodeParser::matchEnumItem(InnerNode *parent, EnumNode *enume) +bool CppCodeParser::matchEnumItem(Aggregate *parent, EnumNode *enume) { if (!match(Tok_Ident)) return false; QString name = previousLexeme(); CodeChunk val; + int parenLevel = 0; if (match(Tok_Equal)) { - while (tok != Tok_Comma && tok != Tok_RightBrace && - tok != Tok_Eoi) { + while (tok != Tok_RightBrace && tok != Tok_Eoi) { + if (tok == Tok_LeftParen) + parenLevel++; + else if (tok == Tok_RightParen) + parenLevel--; + else if (tok == Tok_Comma) { + if (parenLevel <= 0) + break; + } val.append(lexeme()); readToken(); } @@ -1825,7 +1921,7 @@ bool CppCodeParser::matchEnumItem(InnerNode *parent, EnumNode *enume) return true; } -bool CppCodeParser::matchEnumDecl(InnerNode *parent) +bool CppCodeParser::matchEnumDecl(Aggregate *parent) { QString name; @@ -1856,7 +1952,7 @@ bool CppCodeParser::matchEnumDecl(InnerNode *parent) return match(Tok_RightBrace) && match(Tok_Semicolon); } -bool CppCodeParser::matchTypedefDecl(InnerNode *parent) +bool CppCodeParser::matchTypedefDecl(Aggregate *parent) { CodeChunk dataType; QString name; @@ -1876,7 +1972,7 @@ bool CppCodeParser::matchTypedefDecl(InnerNode *parent) return true; } -bool CppCodeParser::matchProperty(InnerNode *parent) +bool CppCodeParser::matchProperty(Aggregate *parent) { int expected_tok = Tok_LeftParen; if (match(Tok_Q_PRIVATE_PROPERTY)) { @@ -1989,7 +2085,7 @@ bool CppCodeParser::matchProperty(InnerNode *parent) /*! Parse a C++ declaration. */ -bool CppCodeParser::matchDeclList(InnerNode *parent) +bool CppCodeParser::matchDeclList(Aggregate *parent) { ExtraFuncData extra; QString templateStuff; @@ -2030,28 +2126,28 @@ bool CppCodeParser::matchDeclList(InnerNode *parent) case Tok_private: readToken(); access = Node::Private; - metaness = FunctionNode::Plain; + metaness_ = FunctionNode::Plain; break; case Tok_protected: readToken(); access = Node::Protected; - metaness = FunctionNode::Plain; + metaness_ = FunctionNode::Plain; break; case Tok_public: readToken(); access = Node::Public; - metaness = FunctionNode::Plain; + metaness_ = FunctionNode::Plain; break; case Tok_signals: case Tok_Q_SIGNALS: readToken(); access = Node::Public; - metaness = FunctionNode::Signal; + metaness_ = FunctionNode::Signal; break; case Tok_slots: case Tok_Q_SLOTS: readToken(); - metaness = FunctionNode::Slot; + metaness_ = FunctionNode::Slot; break; case Tok_Q_OBJECT: readToken(); @@ -2069,29 +2165,25 @@ bool CppCodeParser::matchDeclList(InnerNode *parent) case Tok_Q_DECLARE_SEQUENTIAL_ITERATOR: readToken(); if (match(Tok_LeftParen) && match(Tok_Ident)) - sequentialIteratorClasses.insert(previousLexeme(), - location().fileName()); + sequentialIteratorClasses.insert(previousLexeme(), location().fileName()); match(Tok_RightParen); break; case Tok_Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR: readToken(); if (match(Tok_LeftParen) && match(Tok_Ident)) - mutableSequentialIteratorClasses.insert(previousLexeme(), - location().fileName()); + mutableSequentialIteratorClasses.insert(previousLexeme(), location().fileName()); match(Tok_RightParen); break; case Tok_Q_DECLARE_ASSOCIATIVE_ITERATOR: readToken(); if (match(Tok_LeftParen) && match(Tok_Ident)) - associativeIteratorClasses.insert(previousLexeme(), - location().fileName()); + associativeIteratorClasses.insert(previousLexeme(), location().fileName()); match(Tok_RightParen); break; case Tok_Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR: readToken(); if (match(Tok_LeftParen) && match(Tok_Ident)) - mutableAssociativeIteratorClasses.insert(previousLexeme(), - location().fileName()); + mutableAssociativeIteratorClasses.insert(previousLexeme(), location().fileName()); match(Tok_RightParen); break; case Tok_Q_DECLARE_FLAGS: @@ -2256,15 +2348,15 @@ bool CppCodeParser::matchDocsAndStuff() processOtherMetaCommands(*d, *n); (*n)->setDoc(*d); checkModuleInclusion(*n); - if ((*n)->isInnerNode() && ((InnerNode *)*n)->includes().isEmpty()) { - InnerNode *m = static_cast<InnerNode *>(*n); + if ((*n)->isAggregate() && ((Aggregate *)*n)->includes().isEmpty()) { + Aggregate *m = static_cast<Aggregate *>(*n); while (m->parent() && m->physicalModuleName().isEmpty()) { m = m->parent(); } if (m == *n) - ((InnerNode *)*n)->addInclude((*n)->name()); + ((Aggregate *)*n)->addInclude((*n)->name()); else - ((InnerNode *)*n)->setIncludes(m->includes()); + ((Aggregate *)*n)->setIncludes(m->includes()); } ++d; ++n; @@ -2333,6 +2425,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 @@ -2346,8 +2466,8 @@ bool CppCodeParser::makeFunctionNode(const QString& signature, */ FunctionNode* CppCodeParser::makeFunctionNode(const Doc& doc, const QString& sig, - InnerNode* parent, - Node::Type type, + Aggregate* parent, + Node::NodeType type, bool attached, QString qdoctag) { |