summaryrefslogtreecommitdiffstats
path: root/src/tools/qdoc/cppcodeparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/qdoc/cppcodeparser.cpp')
-rw-r--r--src/tools/qdoc/cppcodeparser.cpp472
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 &param = 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)
{