diff options
Diffstat (limited to 'tools/qdoc3/cppcodeparser.cpp')
-rw-r--r-- | tools/qdoc3/cppcodeparser.cpp | 117 |
1 files changed, 80 insertions, 37 deletions
diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index cabbe38..ce71e51 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -686,20 +686,20 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc, (command == COMMAND_QMLATTACHEDSIGNAL) || (command == COMMAND_QMLATTACHEDMETHOD)) { QString element; - QString name; + QString type; QmlClassNode* qmlClass = 0; - if (splitQmlArg(doc,arg,element,name)) { + if (splitQmlMethodArg(doc,arg,type,element)) { Node* n = tre->findNode(QStringList(element),Node::Fake); 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. } @@ -717,15 +717,15 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc, <type> <element>::<name> This function splits the argument into those three - parts, sets \a type, \a element, and \a property, + parts, sets \a type, \a element, and \a name, and returns true. If any of the parts isn't found, - a debug message is output and false is returned. + a qdoc warning is output and false is returned. */ bool CppCodeParser::splitQmlPropertyArg(const Doc& doc, const QString& arg, QString& type, QString& element, - QString& property) + QString& name) { QStringList blankSplit = arg.split(" "); if (blankSplit.size() > 1) { @@ -733,40 +733,47 @@ bool CppCodeParser::splitQmlPropertyArg(const Doc& doc, QStringList colonSplit(blankSplit[1].split("::")); if (colonSplit.size() > 1) { element = colonSplit[0]; - property = colonSplit[1]; + name = colonSplit[1]; return true; } else - doc.location().warning(tr("Missing QML element name or property name")); + doc.location().warning(tr("Missing parent QML element name")); } else - doc.location().warning(tr("Missing QML property type or property path")); + doc.location().warning(tr("Missing property type")); return false; } /*! A QML signal or method argument has the form... - <element>::<name> + <type> <element>::<name>(<param>, <param>, ...) This function splits the argument into those two parts, sets \a element, and \a name, and returns true. If either of the parts isn't found, a debug message is output and false is returned. */ -bool CppCodeParser::splitQmlArg(const Doc& doc, - const QString& arg, - QString& element, - QString& name) +bool CppCodeParser::splitQmlMethodArg(const Doc& doc, + const QString& arg, + QString& type, + QString& element) { QStringList colonSplit(arg.split("::")); if (colonSplit.size() > 1) { - element = colonSplit[0]; - name = colonSplit[1]; + QStringList blankSplit = colonSplit[0].split(" "); + if (blankSplit.size() > 1) { + type = blankSplit[0]; + element = blankSplit[1]; + } + else { + type = QString(""); + element = colonSplit[0]; + } return true; } else - doc.location().warning(tr("Missing QML element name or signal/method name")); + doc.location().warning(tr("Missing parent QML element or method signature")); return false; } @@ -811,10 +818,10 @@ Node *CppCodeParser::processTopicCommandGroup(const Doc& doc, ++arg; while (arg != args.end()) { if (splitQmlPropertyArg(doc,(*arg),type,element,property)) { - QmlPropertyNode * qmlPropNode = new QmlPropertyNode(qmlPropGroup, - property, - type, - attached); + QmlPropertyNode* qmlPropNode = new QmlPropertyNode(qmlPropGroup, + property, + type, + attached); if (correspondingProperty) { bool writableList = type.startsWith("list") && correspondingProperty->dataType().endsWith('*'); qmlPropNode->setWritable(writableList || correspondingProperty->isWritable()); @@ -1265,7 +1272,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 +1304,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 +1336,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 +1384,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 +1395,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 +1410,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 +1437,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 +1460,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 +2109,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 +2123,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) { |