util/tools/qdoc3/cppcodemarker.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the tools applications of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 /*
       
    43   cppcodemarker.cpp
       
    44 */
       
    45 
       
    46 #include <qdebug.h>
       
    47 #include "atom.h"
       
    48 #include "cppcodemarker.h"
       
    49 #include "node.h"
       
    50 #include "text.h"
       
    51 #include "tree.h"
       
    52 
       
    53 QT_BEGIN_NAMESPACE
       
    54 
       
    55 static int insertTagAround(QString &result, int pos, int len, const QString &tagName,
       
    56                            const QString &attributes = QString())
       
    57 {
       
    58     QString s;
       
    59     //s.reserve(result.size() + tagName.size() * 2 + attributes.size() + 20);
       
    60     s += result.midRef(0, pos);
       
    61     s += QLatin1Char('<');
       
    62     s += tagName;
       
    63     if (!attributes.isEmpty()) {
       
    64         s += QLatin1Char(' ');
       
    65         s += attributes;
       
    66     }
       
    67     s += QLatin1Char('>');
       
    68     s += result.midRef(pos, len);
       
    69     s += QLatin1String("</");
       
    70     s += tagName;
       
    71     s += QLatin1Char('>');
       
    72     s += result.midRef(pos + len);
       
    73     int diff = s.length() - result.length();
       
    74     result = s;
       
    75     return diff;
       
    76 }
       
    77 
       
    78 /*!
       
    79   The constructor does nothing.
       
    80  */
       
    81 CppCodeMarker::CppCodeMarker()
       
    82 {
       
    83     // nothing.
       
    84 }
       
    85 
       
    86 /*!
       
    87   The destructor does nothing.
       
    88  */
       
    89 CppCodeMarker::~CppCodeMarker()
       
    90 {
       
    91     // nothing.
       
    92 }
       
    93 
       
    94 /*!
       
    95   Returns true.
       
    96  */
       
    97 bool CppCodeMarker::recognizeCode(const QString & /* code */)
       
    98 {
       
    99     return true;
       
   100 }
       
   101 
       
   102 /*!
       
   103   Returns true if \a ext is any of a list of file extensions
       
   104   for the C++ language.
       
   105  */
       
   106 bool CppCodeMarker::recognizeExtension(const QString& ext)
       
   107 {
       
   108     return ext == "c" ||
       
   109         ext == "c++" ||
       
   110         ext == "cc" ||
       
   111         ext == "cpp" ||
       
   112         ext == "cxx" ||
       
   113         ext == "ch" ||
       
   114         ext == "h" ||
       
   115         ext == "h++" ||
       
   116         ext == "hh" ||
       
   117         ext == "hpp" ||
       
   118         ext == "hxx";
       
   119 }
       
   120 
       
   121 /*!
       
   122   Returns true if \a lang is either "C" or "Cpp".
       
   123  */
       
   124 bool CppCodeMarker::recognizeLanguage(const QString &lang)
       
   125 {
       
   126     return lang == "C" || lang == "Cpp";
       
   127 }
       
   128 
       
   129 /*!
       
   130   Returns the \a node name, or "()" if \a node is a
       
   131   Node::Function node.
       
   132  */
       
   133 QString CppCodeMarker::plainName(const Node *node)
       
   134 {
       
   135     QString name = node->name();
       
   136     if (node->type() == Node::Function)
       
   137 	name += "()";
       
   138     return name;
       
   139 }
       
   140 
       
   141 QString CppCodeMarker::plainFullName(const Node *node, const Node *relative)
       
   142 {
       
   143     if (node->name().isEmpty()) {
       
   144 	return "global";
       
   145     }
       
   146     else {
       
   147 	QString fullName;
       
   148 	for (;;) {
       
   149 	    fullName.prepend(plainName(node));
       
   150 	    if (node->parent() == relative || node->parent()->name().isEmpty())
       
   151 		break;
       
   152 	    fullName.prepend("::");
       
   153 	    node = node->parent();
       
   154         }
       
   155         return fullName;
       
   156     }
       
   157 }
       
   158 
       
   159 QString CppCodeMarker::markedUpCode(const QString &code,
       
   160                                     const Node *relative,
       
   161 				    const QString &dirPath)
       
   162 {
       
   163     return addMarkUp(protect(code), relative, dirPath);
       
   164 }
       
   165 
       
   166 QString CppCodeMarker::markedUpSynopsis(const Node *node,
       
   167                                         const Node * /* relative */,
       
   168 					SynopsisStyle style)
       
   169 {
       
   170     const int MaxEnumValues = 6;
       
   171     const FunctionNode *func;
       
   172     const PropertyNode *property;
       
   173     const VariableNode *variable;
       
   174     const EnumNode *enume;
       
   175     const TypedefNode *typedeff;
       
   176     QString synopsis;
       
   177     QString extra;
       
   178     QString name;
       
   179 
       
   180     name = taggedNode(node);
       
   181     if (style != Detailed)
       
   182 	name = linkTag(node, name);
       
   183     name = "<@name>" + name + "</@name>";
       
   184 
       
   185     if (style == Detailed && !node->parent()->name().isEmpty() &&
       
   186         node->type() != Node::Property)
       
   187 	name.prepend(taggedNode(node->parent()) + "::");
       
   188 
       
   189     switch (node->type()) {
       
   190     case Node::Namespace:
       
   191 	synopsis = "namespace " + name;
       
   192 	break;
       
   193     case Node::Class:
       
   194 	synopsis = "class " + name;
       
   195 	break;
       
   196     case Node::Function:
       
   197     case Node::QmlSignal:
       
   198     case Node::QmlMethod:
       
   199 	func = (const FunctionNode *) node;
       
   200 	if (style != SeparateList && !func->returnType().isEmpty())
       
   201 	    synopsis = typified(func->returnType()) + " ";
       
   202 	synopsis += name;
       
   203         if (func->metaness() != FunctionNode::MacroWithoutParams) {
       
   204             synopsis += " (";
       
   205 	    if (!func->parameters().isEmpty()) {
       
   206 	        synopsis += " ";
       
   207 	        QList<Parameter>::ConstIterator p = func->parameters().begin();
       
   208 	        while (p != func->parameters().end()) {
       
   209 		    if (p != func->parameters().begin())
       
   210 		        synopsis += ", ";
       
   211 		    synopsis += typified((*p).leftType());
       
   212                     if (style != SeparateList && !(*p).name().isEmpty())
       
   213                         synopsis +=
       
   214                             " <@param>" + protect((*p).name()) + "</@param>";
       
   215                     synopsis += protect((*p).rightType());
       
   216 		    if (style != SeparateList && !(*p).defaultValue().isEmpty())
       
   217 		        synopsis += " = " + protect((*p).defaultValue());
       
   218 		    ++p;
       
   219 	        }
       
   220 	        synopsis += " ";
       
   221 	    }
       
   222 	    synopsis += ")";
       
   223         }
       
   224 	if (func->isConst())
       
   225 	    synopsis += " const";
       
   226 
       
   227 	if (style == Summary || style == Accessors) {
       
   228 	    if (func->virtualness() != FunctionNode::NonVirtual)
       
   229 		synopsis.prepend("virtual ");
       
   230 	    if (func->virtualness() == FunctionNode::PureVirtual)
       
   231 		synopsis.append(" = 0");
       
   232 	}
       
   233         else if (style == SeparateList) {
       
   234             if (!func->returnType().isEmpty() && func->returnType() != "void")
       
   235                 synopsis += " : " + typified(func->returnType());
       
   236         }
       
   237         else {
       
   238 	    QStringList bracketed;
       
   239 	    if (func->isStatic()) {
       
   240 		bracketed += "static";
       
   241 	    }
       
   242             else if (func->virtualness() != FunctionNode::NonVirtual) {
       
   243 		if (func->virtualness() == FunctionNode::PureVirtual)
       
   244 		    bracketed += "pure";
       
   245 		bracketed += "virtual";
       
   246 	    }
       
   247 
       
   248 	    if (func->access() == Node::Protected) {
       
   249 		bracketed += "protected";
       
   250 	    }
       
   251             else if (func->access() == Node::Private) {
       
   252 		bracketed += "private";
       
   253 	    }
       
   254 
       
   255 	    if (func->metaness() == FunctionNode::Signal) {
       
   256 		bracketed += "signal";
       
   257 	    }
       
   258             else if (func->metaness() == FunctionNode::Slot) {
       
   259 		bracketed += "slot";
       
   260 	    }
       
   261 	    if (!bracketed.isEmpty())
       
   262 		extra += " [" + bracketed.join(" ") + "]";
       
   263 	}
       
   264 	break;
       
   265     case Node::Enum:
       
   266 	enume = static_cast<const EnumNode *>(node);
       
   267 	synopsis = "enum " + name;
       
   268         if (style == Summary) {
       
   269             synopsis += " { ";
       
   270 
       
   271             QStringList documentedItems = enume->doc().enumItemNames();
       
   272             if (documentedItems.isEmpty()) {
       
   273                 foreach (const EnumItem &item, enume->items())
       
   274                     documentedItems << item.name();
       
   275             }
       
   276             QStringList omitItems = enume->doc().omitEnumItemNames();
       
   277             foreach (const QString &item, omitItems)
       
   278                 documentedItems.removeAll(item);
       
   279 
       
   280             if (documentedItems.size() <= MaxEnumValues) {
       
   281                 for (int i = 0; i < documentedItems.size(); ++i) {
       
   282 	            if (i != 0)
       
   283 		        synopsis += ", ";
       
   284 		    synopsis += documentedItems.at(i);
       
   285                 }
       
   286             }
       
   287             else {
       
   288                 for (int i = 0; i < documentedItems.size(); ++i) {
       
   289 		    if (i < MaxEnumValues-2 || i == documentedItems.size()-1) {
       
   290 	                if (i != 0)
       
   291 		            synopsis += ", ";
       
   292 		        synopsis += documentedItems.at(i);
       
   293 		    }
       
   294                     else if (i == MaxEnumValues - 1) {
       
   295 		        synopsis += ", ...";
       
   296 		    }
       
   297                 }
       
   298             }
       
   299 	    if (!documentedItems.isEmpty())
       
   300 		synopsis += " ";
       
   301 	    synopsis += "}";
       
   302 	}
       
   303 	break;
       
   304     case Node::Typedef:
       
   305         typedeff = static_cast<const TypedefNode *>(node);
       
   306         if (typedeff->associatedEnum()) {
       
   307             synopsis = "flags " + name;
       
   308         }
       
   309         else {
       
   310             synopsis = "typedef " + name;
       
   311         }
       
   312 	break;
       
   313     case Node::Property:
       
   314 	property = static_cast<const PropertyNode *>(node);
       
   315 	synopsis = name + " : " + typified(property->qualifiedDataType());
       
   316 	break;
       
   317     case Node::Variable:
       
   318 	variable = static_cast<const VariableNode *>(node);
       
   319         if (style == SeparateList) {
       
   320             synopsis = name + " : " + typified(variable->dataType());
       
   321         }
       
   322         else {
       
   323             synopsis = typified(variable->leftType()) + " " +
       
   324                 name + protect(variable->rightType());
       
   325         }
       
   326 	break;
       
   327     default:
       
   328 	synopsis = name;
       
   329     }
       
   330 
       
   331     if (style == Summary) {
       
   332 	if (node->status() == Node::Preliminary) {
       
   333 	    extra += " (preliminary)";
       
   334 	}
       
   335         else if (node->status() == Node::Deprecated) {
       
   336 	    extra += " (deprecated)";
       
   337 	}
       
   338         else if (node->status() == Node::Obsolete) {
       
   339 	    extra += " (obsolete)";
       
   340 	}
       
   341     }
       
   342 
       
   343     if (!extra.isEmpty()) {
       
   344 	extra.prepend("<@extra>");
       
   345 	extra.append("</@extra>");
       
   346     }
       
   347     return synopsis + extra;
       
   348 }
       
   349 
       
   350 #ifdef QDOC_QML
       
   351 /*!
       
   352  */
       
   353 QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary)
       
   354 {
       
   355     QString name = taggedQmlNode(node);
       
   356     if (summary) {
       
   357 	name = linkTag(node,name);
       
   358     } else if (node->type() == Node::QmlProperty) {
       
   359         const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
       
   360         if (pn->isAttached())
       
   361             name.prepend(pn->element() + QLatin1Char('.'));
       
   362     }
       
   363     name = "<@name>" + name + "</@name>";
       
   364     QString synopsis = name;
       
   365     if (node->type() == Node::QmlProperty) {
       
   366         const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
       
   367         synopsis += " : " + typified(pn->dataType());
       
   368     }
       
   369 
       
   370     QString extra;
       
   371     if (summary) {
       
   372 	if (node->status() == Node::Preliminary) {
       
   373 	    extra += " (preliminary)";
       
   374 	}
       
   375         else if (node->status() == Node::Deprecated) {
       
   376 	    extra += " (deprecated)";
       
   377 	}
       
   378         else if (node->status() == Node::Obsolete) {
       
   379 	    extra += " (obsolete)";
       
   380 	}
       
   381     }
       
   382 
       
   383     if (!extra.isEmpty()) {
       
   384 	extra.prepend("<@extra>");
       
   385 	extra.append("</@extra>");
       
   386     }
       
   387     return synopsis + extra;
       
   388 }
       
   389 #endif
       
   390 
       
   391 QString CppCodeMarker::markedUpName(const Node *node)
       
   392 {
       
   393     QString name = linkTag(node, taggedNode(node));
       
   394     if (node->type() == Node::Function)
       
   395 	name += "()";
       
   396     return name;
       
   397 }
       
   398 
       
   399 QString CppCodeMarker::markedUpFullName(const Node *node, const Node *relative)
       
   400 {
       
   401     if (node->name().isEmpty()) {
       
   402 	return "global";
       
   403     }
       
   404     else {
       
   405 	QString fullName;
       
   406 	for (;;) {
       
   407 	    fullName.prepend(markedUpName(node));
       
   408 	    if (node->parent() == relative || node->parent()->name().isEmpty())
       
   409 		break;
       
   410 	    fullName.prepend("<@op>::</@op>");
       
   411 	    node = node->parent();
       
   412         }
       
   413         return fullName;
       
   414     }
       
   415 }
       
   416 
       
   417 QString CppCodeMarker::markedUpEnumValue(const QString &enumValue,
       
   418                                          const Node *relative)
       
   419 {
       
   420     const Node *node = relative->parent();
       
   421     QString fullName;
       
   422     while (node->parent()) {
       
   423 	fullName.prepend(markedUpName(node));
       
   424 	if (node->parent() == relative || node->parent()->name().isEmpty())
       
   425 	    break;
       
   426 	fullName.prepend("<@op>::</@op>");
       
   427 	node = node->parent();
       
   428     }
       
   429     if (!fullName.isEmpty())
       
   430         fullName.append("<@op>::</@op>");
       
   431     fullName.append(enumValue);
       
   432     return fullName;
       
   433 }
       
   434 
       
   435 QString CppCodeMarker::markedUpIncludes(const QStringList& includes)
       
   436 {
       
   437     QString code;
       
   438 
       
   439     QStringList::ConstIterator inc = includes.begin();
       
   440     while (inc != includes.end()) {
       
   441 	code += "#include &lt;<@headerfile>" + *inc + "</@headerfile>&gt;\n";
       
   442 	++inc;
       
   443     }
       
   444     return addMarkUp(code, 0, "");
       
   445 }
       
   446 
       
   447 QString CppCodeMarker::functionBeginRegExp(const QString& funcName)
       
   448 {
       
   449     return "^" + QRegExp::escape(funcName) + "$";
       
   450 
       
   451 }
       
   452 
       
   453 QString CppCodeMarker::functionEndRegExp(const QString& /* funcName */)
       
   454 {
       
   455     return "^\\}$";
       
   456 }
       
   457 
       
   458 #if 0
       
   459 	    FastSection privateReimpFuncs(classe,
       
   460                                           "Private Reimplemented Functions",
       
   461                                           "private reimplemented function",
       
   462                                           "private reimplemented functions");
       
   463 	    FastSection protectedReimpFuncs(classe,
       
   464                                             "Protected Reimplemented Functions",
       
   465                                             "protected reimplemented function",
       
   466                                             "protected reimplemented functions");
       
   467 	    FastSection publicReimpFuncs(classe,
       
   468                                          "Public Reimplemented Functions",
       
   469                                          "public reimplemented function",
       
   470                                          "public reimplemented functions");
       
   471 #endif
       
   472 
       
   473 QList<Section> CppCodeMarker::sections(const InnerNode *inner,
       
   474                                        SynopsisStyle style,
       
   475                                        Status status)
       
   476 {
       
   477     QList<Section> sections;
       
   478 
       
   479     if (inner->type() == Node::Class) {
       
   480         const ClassNode *classe = static_cast<const ClassNode *>(inner);
       
   481 
       
   482         if (style == Summary) {
       
   483 	    FastSection privateFunctions(classe,
       
   484                                          "Private Functions",
       
   485                                          "private function",
       
   486 				         "private functions");
       
   487 	    FastSection privateSlots(classe, "Private Slots", "private slot", "private slots");
       
   488 	    FastSection privateTypes(classe, "Private Types", "private type", "private types");
       
   489 	    FastSection protectedFunctions(classe,
       
   490                                            "Protected Functions",
       
   491                                            "protected function",
       
   492 				           "protected functions");
       
   493 	    FastSection protectedSlots(classe,
       
   494                                        "Protected Slots",
       
   495                                        "protected slot",
       
   496                                        "protected slots");
       
   497 	    FastSection protectedTypes(classe,
       
   498                                        "Protected Types",
       
   499                                        "protected type",
       
   500                                        "protected types");
       
   501 	    FastSection protectedVariables(classe,
       
   502                                            "Protected Variables",
       
   503                                            "protected type",
       
   504                                            "protected variables");
       
   505 	    FastSection publicFunctions(classe,
       
   506                                         "Public Functions",
       
   507                                         "public function",
       
   508                                         "public functions");
       
   509 	    FastSection publicSignals(classe, "Signals", "signal", "signals");
       
   510 	    FastSection publicSlots(classe, "Public Slots", "public slot", "public slots");
       
   511 	    FastSection publicTypes(classe, "Public Types", "public type", "public types");
       
   512 	    FastSection publicVariables(classe,
       
   513                                         "Public Variables",
       
   514                                         "public type",
       
   515                                         "public variables");
       
   516 	    FastSection properties(classe, "Properties", "property", "properties");
       
   517 	    FastSection relatedNonMembers(classe,
       
   518                                           "Related Non-Members",
       
   519                                           "related non-member",
       
   520                                           "related non-members");
       
   521 	    FastSection staticPrivateMembers(classe,
       
   522                                              "Static Private Members",
       
   523                                              "static private member",
       
   524 					     "static private members");
       
   525 	    FastSection staticProtectedMembers(classe,
       
   526                                                "Static Protected Members",
       
   527 					       "static protected member",
       
   528                                                "static protected members");
       
   529 	    FastSection staticPublicMembers(classe,
       
   530                                             "Static Public Members",
       
   531                                             "static public member",
       
   532 					    "static public members");
       
   533             FastSection macros(inner, "Macros", "macro", "macros");
       
   534 
       
   535 	    NodeList::ConstIterator r = classe->relatedNodes().begin();
       
   536             while (r != classe->relatedNodes().end()) {
       
   537                 if ((*r)->type() == Node::Function) {
       
   538                     FunctionNode *func = static_cast<FunctionNode *>(*r);
       
   539                     if (func->isMacro())
       
   540                         insert(macros, *r, style, status);
       
   541                     else
       
   542                         insert(relatedNonMembers, *r, style, status);
       
   543                 }
       
   544                 else {
       
   545                     insert(relatedNonMembers, *r, style, status);
       
   546                 }
       
   547 	        ++r;
       
   548             }
       
   549 
       
   550 	    QStack<const ClassNode *> stack;
       
   551 	    stack.push(classe);
       
   552 
       
   553 	    while (!stack.isEmpty()) {
       
   554 	        const ClassNode *ancestorClass = stack.pop();
       
   555 
       
   556 	        NodeList::ConstIterator c = ancestorClass->childNodes().begin();
       
   557 	        while (c != ancestorClass->childNodes().end()) {
       
   558 	            bool isSlot = false;
       
   559 	            bool isSignal = false;
       
   560 	            bool isStatic = false;
       
   561 	            if ((*c)->type() == Node::Function) {
       
   562 		        const FunctionNode *func = (const FunctionNode *) *c;
       
   563 		        isSlot = (func->metaness() == FunctionNode::Slot);
       
   564 		        isSignal = (func->metaness() == FunctionNode::Signal);
       
   565 		        isStatic = func->isStatic();
       
   566 	            }
       
   567                     else if ((*c)->type() == Node::Variable) {
       
   568                         const VariableNode *var = static_cast<const VariableNode *>(*c);
       
   569                         isStatic = var->isStatic();
       
   570                     }
       
   571 
       
   572 	            switch ((*c)->access()) {
       
   573 	            case Node::Public:
       
   574 		        if (isSlot) {
       
   575 		            insert(publicSlots, *c, style, status);
       
   576 		        }
       
   577                         else if (isSignal) {
       
   578 		            insert(publicSignals, *c, style, status);
       
   579 		        }
       
   580                         else if (isStatic) {
       
   581                             if ((*c)->type() != Node::Variable
       
   582                                     || !(*c)->doc().isEmpty())
       
   583 		                insert(staticPublicMembers,*c,style,status);
       
   584 		        }
       
   585                         else if ((*c)->type() == Node::Property) {
       
   586                             insert(properties, *c, style, status);
       
   587 		        }
       
   588                         else if ((*c)->type() == Node::Variable) {
       
   589                             if (!(*c)->doc().isEmpty())
       
   590                                 insert(publicVariables, *c, style, status);
       
   591 		        }
       
   592                         else if ((*c)->type() == Node::Function) {
       
   593                             if (!insertReimpFunc(publicFunctions,*c,status))
       
   594                                 insert(publicFunctions, *c, style, status);
       
   595 		        }
       
   596                         else {
       
   597 		            insert(publicTypes, *c, style, status);
       
   598 		        }
       
   599 		        break;
       
   600 	            case Node::Protected:
       
   601 		        if (isSlot) {
       
   602 		            insert(protectedSlots, *c, style, status);
       
   603 		        }
       
   604                         else if (isStatic) {
       
   605                             if ((*c)->type() != Node::Variable
       
   606                                     || !(*c)->doc().isEmpty())
       
   607 		                insert(staticProtectedMembers,*c,style,status);
       
   608 		        }
       
   609                         else if ((*c)->type() == Node::Variable) {
       
   610                             if (!(*c)->doc().isEmpty())
       
   611                                 insert(protectedVariables,*c,style,status);
       
   612 		        }
       
   613                         else if ((*c)->type() == Node::Function) {
       
   614                             if (!insertReimpFunc(protectedFunctions,*c,status))
       
   615                                 insert(protectedFunctions, *c, style, status);
       
   616 		        }
       
   617                         else {
       
   618 		            insert(protectedTypes, *c, style, status);
       
   619 		        }
       
   620 		        break;
       
   621 	            case Node::Private:
       
   622 		        if (isSlot) {
       
   623 		            insert(privateSlots, *c, style, status);
       
   624 		        }
       
   625                         else if (isStatic) {
       
   626                             if ((*c)->type() != Node::Variable
       
   627                                     || !(*c)->doc().isEmpty())
       
   628 		                insert(staticPrivateMembers,*c,style,status);
       
   629 		        }
       
   630                         else if ((*c)->type() == Node::Function) {
       
   631                             if (!insertReimpFunc(privateFunctions,*c,status))
       
   632                                 insert(privateFunctions, *c, style, status);
       
   633 		        }
       
   634                         else {
       
   635 		            insert(privateTypes,*c,style,status);
       
   636 		        }
       
   637 	            }
       
   638 	            ++c;
       
   639 	        }
       
   640 
       
   641 	        QList<RelatedClass>::ConstIterator r =
       
   642                     ancestorClass->baseClasses().begin();
       
   643 	        while (r != ancestorClass->baseClasses().end()) {
       
   644 		    stack.prepend((*r).node);
       
   645 		    ++r;
       
   646 	        }
       
   647 	    }
       
   648 
       
   649 	    append(sections, publicTypes);
       
   650 	    append(sections, properties);
       
   651 	    append(sections, publicFunctions);
       
   652 	    append(sections, publicSlots);
       
   653 	    append(sections, publicSignals);
       
   654 	    append(sections, publicVariables);
       
   655 	    append(sections, staticPublicMembers);
       
   656 	    append(sections, protectedTypes);
       
   657 	    append(sections, protectedFunctions);
       
   658 	    append(sections, protectedSlots);
       
   659 	    append(sections, protectedVariables);
       
   660 	    append(sections, staticProtectedMembers);
       
   661 	    append(sections, privateTypes);
       
   662 	    append(sections, privateFunctions);
       
   663 	    append(sections, privateSlots);
       
   664 	    append(sections, staticPrivateMembers);
       
   665 	    append(sections, relatedNonMembers);
       
   666             append(sections, macros);
       
   667         }
       
   668         else if (style == Detailed) {
       
   669 	    FastSection memberFunctions(classe,"Member Function Documentation");
       
   670 	    FastSection memberTypes(classe,"Member Type Documentation");
       
   671 	    FastSection memberVariables(classe,"Member Variable Documentation");
       
   672 	    FastSection properties(classe,"Property Documentation");
       
   673 	    FastSection relatedNonMembers(classe,"Related Non-Members");
       
   674 	    FastSection macros(classe,"Macro Documentation");
       
   675 
       
   676 	    NodeList::ConstIterator r = classe->relatedNodes().begin();
       
   677             while (r != classe->relatedNodes().end()) {
       
   678                 if ((*r)->type() == Node::Function) {
       
   679                     FunctionNode *func = static_cast<FunctionNode *>(*r);
       
   680                     if (func->isMacro())
       
   681                         insert(macros, *r, style, status);
       
   682                     else
       
   683                         insert(relatedNonMembers, *r, style, status);
       
   684                 }
       
   685                 else {
       
   686                     insert(relatedNonMembers, *r, style, status);
       
   687                 }
       
   688 	        ++r;
       
   689             }
       
   690 
       
   691 	    NodeList::ConstIterator c = classe->childNodes().begin();
       
   692 	    while (c != classe->childNodes().end()) {
       
   693 	        if ((*c)->type() == Node::Enum ||
       
   694                     (*c)->type() == Node::Typedef) {
       
   695 		    insert(memberTypes, *c, style, status);
       
   696 	        }
       
   697                 else if ((*c)->type() == Node::Property) {
       
   698 		    insert(properties, *c, style, status);
       
   699 	        }
       
   700                 else if ((*c)->type() == Node::Variable) {
       
   701                     if (!(*c)->doc().isEmpty())
       
   702 		        insert(memberVariables, *c, style, status);
       
   703 	        }
       
   704                 else if ((*c)->type() == Node::Function) {
       
   705 		    FunctionNode *function = static_cast<FunctionNode *>(*c);
       
   706                     if (!function->associatedProperty())
       
   707 		        insert(memberFunctions, function, style, status);
       
   708 	        }
       
   709 	        ++c;
       
   710 	    }
       
   711 
       
   712 	    append(sections, memberTypes);
       
   713 	    append(sections, properties);
       
   714 	    append(sections, memberFunctions);
       
   715 	    append(sections, memberVariables);
       
   716 	    append(sections, relatedNonMembers);
       
   717 	    append(sections, macros);
       
   718         }
       
   719         else {
       
   720 	    FastSection all(classe);
       
   721 
       
   722 	    QStack<const ClassNode *> stack;
       
   723 	    stack.push(classe);
       
   724 
       
   725 	    while (!stack.isEmpty()) {
       
   726 	        const ClassNode *ancestorClass = stack.pop();
       
   727 
       
   728 	        NodeList::ConstIterator c = ancestorClass->childNodes().begin();
       
   729 	        while (c != ancestorClass->childNodes().end()) {
       
   730 		    if ((*c)->access() != Node::Private &&
       
   731                         (*c)->type() != Node::Property)
       
   732 		        insert(all, *c, style, status);
       
   733 		    ++c;
       
   734 	        }
       
   735 
       
   736 	        QList<RelatedClass>::ConstIterator r =
       
   737                     ancestorClass->baseClasses().begin();
       
   738 	        while (r != ancestorClass->baseClasses().end()) {
       
   739 		    stack.prepend((*r).node);
       
   740 		    ++r;
       
   741 	        }
       
   742 	    }
       
   743 	    append(sections, all);
       
   744         }
       
   745     }
       
   746     else {
       
   747         if (style == Summary || style == Detailed) {
       
   748 	    FastSection namespaces(inner,
       
   749                                    "Namespaces",
       
   750                                    "namespace",
       
   751                                    "namespaces");
       
   752             FastSection classes(inner,
       
   753                                 "Classes",
       
   754                                 "class",
       
   755                                 "classes");
       
   756             FastSection types(inner,
       
   757                               style == Summary ?
       
   758                               "Types" : "Type Documentation",
       
   759                               "type",
       
   760 			      "types");
       
   761             FastSection functions(inner,
       
   762                                   style == Summary ?
       
   763                                   "Functions" : "Function Documentation",
       
   764 			          "function",
       
   765                                   "functions");
       
   766             FastSection macros(inner,
       
   767                                style == Summary ?
       
   768                                "Macros" : "Macro Documentation",
       
   769                                "macro",
       
   770                                "macros");
       
   771 
       
   772 	    NodeList nodeList = inner->childNodes();
       
   773             nodeList += inner->relatedNodes();
       
   774 
       
   775 	    NodeList::ConstIterator n = nodeList.begin();
       
   776             while (n != nodeList.end()) {
       
   777 	        switch ((*n)->type()) {
       
   778                 case Node::Namespace:
       
   779 		    insert(namespaces, *n, style, status);
       
   780                     break;
       
   781 	        case Node::Class:
       
   782 		    insert(classes, *n, style, status);
       
   783                     break;
       
   784 	        case Node::Enum:
       
   785 	        case Node::Typedef:
       
   786 		    insert(types, *n, style, status);
       
   787                     break;
       
   788 	        case Node::Function:
       
   789                     {
       
   790                         FunctionNode *func = static_cast<FunctionNode *>(*n);
       
   791                         if (func->isMacro())
       
   792 		            insert(macros, *n, style, status);
       
   793                         else
       
   794 		            insert(functions, *n, style, status);
       
   795                     }
       
   796                     break;
       
   797 	        default:
       
   798 		    ;
       
   799 	        }
       
   800 	        ++n;
       
   801             }
       
   802             append(sections, namespaces);
       
   803             append(sections, classes);
       
   804             append(sections, types);
       
   805             append(sections, functions);
       
   806             append(sections, macros);
       
   807         }
       
   808     }
       
   809 
       
   810     return sections;
       
   811 }
       
   812 
       
   813 const Node *CppCodeMarker::resolveTarget(const QString &target,
       
   814                                          const Tree *tree,
       
   815                                          const Node *relative)
       
   816 {
       
   817     if (target.endsWith("()")) {
       
   818         const FunctionNode *func;
       
   819         QString funcName = target;
       
   820         funcName.chop(2);
       
   821 
       
   822         QStringList path = funcName.split("::");
       
   823         if ((func = tree->findFunctionNode(path,
       
   824                                            relative,
       
   825                                            Tree::SearchBaseClasses))
       
   826                 && func->metaness() != FunctionNode::MacroWithoutParams)
       
   827             return func;
       
   828     }
       
   829     else if (target.contains("#")) {
       
   830         // ### this doesn't belong here; get rid of TargetNode hack
       
   831         int hashAt = target.indexOf("#");
       
   832         QString link = target.left(hashAt);
       
   833         QString ref = target.mid(hashAt + 1);
       
   834         const Node *node;
       
   835         if (link.isEmpty()) {
       
   836             node = relative;
       
   837         }
       
   838         else {
       
   839             QStringList path(link);
       
   840             node = tree->findNode(path, tree->root(), Tree::SearchBaseClasses);
       
   841         }
       
   842         if (node && node->isInnerNode()) {
       
   843             const Atom *atom = node->doc().body().firstAtom();
       
   844             while (atom) {
       
   845                 if (atom->type() == Atom::Target && atom->string() == ref) {
       
   846                     Node *parentNode = const_cast<Node *>(node);
       
   847                     return new TargetNode(static_cast<InnerNode*>(parentNode),
       
   848                                           ref);
       
   849                 }
       
   850                 atom = atom->next();
       
   851             }
       
   852         }
       
   853     }
       
   854     else {
       
   855         QStringList path = target.split("::");
       
   856         const Node *node;
       
   857         if ((node = tree->findNode(path,
       
   858                                    relative,
       
   859                                    Tree::SearchBaseClasses |
       
   860                                    Tree::SearchEnumValues |
       
   861                                    Tree::NonFunction)))
       
   862             return node;
       
   863     }
       
   864     return 0;
       
   865 }
       
   866 
       
   867 QString CppCodeMarker::addMarkUp(const QString& protectedCode,
       
   868                                  const Node * /* relative */,
       
   869                                  const QString& /* dirPath */)
       
   870 {
       
   871     static QRegExp globalInclude("#include +&lt;([^<>&]+)&gt;");
       
   872     static QRegExp yHasTypeX("(?:^|\n *)([a-zA-Z_][a-zA-Z_0-9]*)"
       
   873 	                     "(?:&lt;[^;{}]+&gt;)?(?: *(?:\\*|&amp;) *| +)"
       
   874 	                     "([a-zA-Z_][a-zA-Z_0-9]*)? *[,;()=]");
       
   875     static QRegExp xNewY("([a-zA-Z_][a-zA-Z_0-9]*) *= *new +([a-zA-Z_0-9]+)");
       
   876     static QRegExp xDotY("\\b([a-zA-Z_][a-zA-Z_0-9]*) *(?:\\.|-&gt;|,[ \n]*S(?:IGNAL|LOT)\\() *"
       
   877 	                 "([a-zA-Z_][a-zA-Z_0-9]*)(?= *\\()");
       
   878     static QRegExp xIsStaticZOfY("[\n:;{(=] *(([a-zA-Z_0-9]+)::([a-zA-Z_0-9]+))(?= *\\()");
       
   879     static QRegExp classX("[:,][ \n]*(?:p(?:ublic|r(?:otected|ivate))[ \n]+)?"
       
   880                           "([a-zA-Z_][a-zA-Z_0-9]*)");
       
   881     static QRegExp globalX("[\n{()=] *([a-zA-Z_][a-zA-Z_0-9]*)[ \n]*\\(");
       
   882     static QRegExp multiLineComment("/(?:( )?\\*(?:[^*]+|\\*(?! /))*\\*\\1/)");
       
   883     multiLineComment.setMinimal(true);
       
   884     static QRegExp singleLineComment("//(?!!)[^!\n]*");
       
   885     static QRegExp preprocessor("(?:^|\n)(#[ \t]*(?:include|if|elif|endif|error|pragma|define"
       
   886                                 "|warning)(?:(?:\\\\\n|\\n#)[^\n]*)*)");
       
   887     static QRegExp literals("&quot;(?:[^\\\\&]|\\\\[^\n]|&(?!quot;))*&quot;"
       
   888                             "|'(?:[^\\\\]|\\\\(?:[^x0-9']|x[0-9a-f]{1,4}|[0-9]{1,3}))'");
       
   889 
       
   890     QString result = protectedCode;
       
   891     int pos;
       
   892 
       
   893     if (!hurryUp()) {
       
   894         /*
       
   895           Mark global includes. For example:
       
   896 
       
   897           #include &lt;<@headerfile>QString</@headerfile>
       
   898         */
       
   899         pos = 0;
       
   900         while ((pos = result.indexOf(globalInclude, pos)) != -1)
       
   901             pos += globalInclude.matchedLength()
       
   902                    + insertTagAround(result,
       
   903                                      globalInclude.pos(1),
       
   904                                      globalInclude.cap(1).length(),
       
   905                                      "@headerfile");
       
   906 
       
   907         /*
       
   908             Look for variable definitions and similar constructs, mark
       
   909             the data type, and remember the type of the variable.
       
   910         */
       
   911         QMap<QString, QSet<QString> > typesForVariable;
       
   912         pos = 0;
       
   913         while ((pos = yHasTypeX.indexIn(result, pos)) != -1) {
       
   914 	    QString x = yHasTypeX.cap(1);
       
   915 	    QString y = yHasTypeX.cap(2);
       
   916 
       
   917 	    if (!y.isEmpty())
       
   918 	        typesForVariable[y].insert(x);
       
   919 
       
   920 	    /*
       
   921                 Without the minus one at the end, 'void member(Class
       
   922                 var)' would give 'member' as a variable of type 'void',
       
   923                 but would ignore 'Class var'. (### Is that true?)
       
   924 	    */
       
   925             pos += yHasTypeX.matchedLength()
       
   926                    + insertTagAround(result,
       
   927                                      yHasTypeX.pos(1),
       
   928                                      x.length(),
       
   929                                      "@type") - 1;
       
   930         }
       
   931 
       
   932         /*
       
   933             Do syntax highlighting of preprocessor directives.
       
   934         */
       
   935         pos = 0;
       
   936         while ((pos = preprocessor.indexIn(result, pos)) != -1)
       
   937             pos += preprocessor.matchedLength()
       
   938                    + insertTagAround(result,
       
   939                                      preprocessor.pos(1),
       
   940                                      preprocessor.cap(1).length(),
       
   941                                      "@preprocessor");
       
   942 
       
   943         /*
       
   944             Deal with string and character literals.
       
   945         */
       
   946         pos = 0;
       
   947         while ((pos = literals.indexIn(result, pos)) != -1)
       
   948             pos += literals.matchedLength()
       
   949                    + insertTagAround(result,
       
   950                                      pos,
       
   951                                      literals.matchedLength(),
       
   952                                      result.at(pos) ==
       
   953                                        QLatin1Char(' ') ? "@string" : "@char");
       
   954 
       
   955         /*
       
   956             Look for 'var = new Class'.
       
   957         */
       
   958         pos = 0;
       
   959         while ((pos = xNewY.indexIn(result, pos)) != -1) {
       
   960 	    QString x = xNewY.cap(1);
       
   961 	    QString y = xNewY.cap(2);
       
   962 	    typesForVariable[x].insert(y);
       
   963 
       
   964 	    pos += xNewY.matchedLength() + insertTagAround(result,
       
   965                                                            xNewY.pos(2),
       
   966                                                            y.length(),
       
   967                                                            "@type");
       
   968         }
       
   969 
       
   970         /*
       
   971             Insert some stuff that cannot harm.
       
   972         */
       
   973         typesForVariable["qApp"].insert("QApplication");
       
   974 
       
   975         /*
       
   976             Add link to ': Class'.
       
   977         */
       
   978         pos = 0;
       
   979         while ((pos = classX.indexIn(result, pos)) != -1)
       
   980 	    pos += classX.matchedLength()
       
   981                    + insertTagAround(result,
       
   982                                      classX.pos(1),
       
   983                                      classX.cap(1).length(),
       
   984                                      "@type") - 1;
       
   985 
       
   986         /*
       
   987             Find use of any of
       
   988 
       
   989                 var.method()
       
   990 	        var->method()
       
   991 	        var, SIGNAL(method())
       
   992 	        var, SLOT(method()).
       
   993         */
       
   994         pos = 0;
       
   995         while ((pos = xDotY.indexIn(result, pos)) != -1) {
       
   996 	    QString x = xDotY.cap(1);
       
   997 	    QString y = xDotY.cap(2);
       
   998 
       
   999 	    QSet<QString> types = typesForVariable.value(x);
       
  1000             pos += xDotY.matchedLength()
       
  1001                    + insertTagAround(result,
       
  1002                                      xDotY.pos(2),
       
  1003                                      xDotY.cap(2).length(),
       
  1004                                      "@func",
       
  1005                                      (types.count() == 1) ? "target=\""
       
  1006                                         + protect(*types.begin() + "::" + y)
       
  1007                                         + "()\"" : QString());
       
  1008         }
       
  1009 
       
  1010         /*
       
  1011             Add link to 'Class::method()'.
       
  1012         */
       
  1013         pos = 0;
       
  1014         while ((pos = xIsStaticZOfY.indexIn(result, pos)) != -1) {
       
  1015 	    QString x = xIsStaticZOfY.cap(1);
       
  1016 	    QString z = xIsStaticZOfY.cap(3);
       
  1017 
       
  1018             pos += insertTagAround(result,
       
  1019                                    xIsStaticZOfY.pos(3),
       
  1020                                    z.length(),
       
  1021                                    "@func",
       
  1022                                    "target=\"" + protect(x) + "()\"");
       
  1023             pos += insertTagAround(result,
       
  1024                                    xIsStaticZOfY.pos(2),
       
  1025                                    xIsStaticZOfY.cap(2).length(),
       
  1026                                    "@type");
       
  1027             pos += xIsStaticZOfY.matchedLength() - 1;
       
  1028         }
       
  1029 
       
  1030         /*
       
  1031             Add link to 'globalFunction()'.
       
  1032         */
       
  1033         pos = 0;
       
  1034         while ((pos = globalX.indexIn(result, pos)) != -1) {
       
  1035             QString x = globalX.cap(1);
       
  1036 	    if (x != "QT_FORWARD_DECLARE_CLASS") {
       
  1037                 pos += globalX.matchedLength()
       
  1038                        + insertTagAround(result,
       
  1039                                          globalX.pos(1),
       
  1040                                          x.length(),
       
  1041                                          "@func",
       
  1042                                          "target=\"" + protect(x) + "()\"") - 1;
       
  1043             }
       
  1044             else
       
  1045                 pos += globalX.matchedLength();
       
  1046         }
       
  1047     }
       
  1048 
       
  1049     /*
       
  1050         Do syntax highlighting of comments. Also alter the code in a
       
  1051         minor way, so that we can include comments in documentation
       
  1052         comments.
       
  1053     */
       
  1054     pos = 0;
       
  1055     while (pos != -1) {
       
  1056         int mlpos;
       
  1057         int slpos;
       
  1058         int len;
       
  1059         slpos = singleLineComment.indexIn(result, pos);
       
  1060         mlpos = multiLineComment.indexIn(result, pos);
       
  1061 
       
  1062         if (slpos == -1 && mlpos == -1)
       
  1063             break;
       
  1064 
       
  1065         if (slpos == -1) {
       
  1066             pos = mlpos;
       
  1067             len = multiLineComment.matchedLength();
       
  1068         }
       
  1069         else if (mlpos == -1) {
       
  1070             pos = slpos;
       
  1071             len = singleLineComment.matchedLength();
       
  1072         }
       
  1073         else {
       
  1074             if (slpos < mlpos) {
       
  1075                 pos = slpos;
       
  1076                 len = singleLineComment.matchedLength();
       
  1077             }
       
  1078             else {
       
  1079                 pos = mlpos;
       
  1080                 len = multiLineComment.matchedLength();
       
  1081             }
       
  1082         }
       
  1083 
       
  1084         if (result.at(pos + 1) == QLatin1Char(' ')) {
       
  1085             result.remove(pos + len - 2, 1);
       
  1086             result.remove(pos + 1, 1);
       
  1087             len -= 2;
       
  1088 
       
  1089             forever {
       
  1090                 int endcodePos = result.indexOf("\\ endcode", pos);
       
  1091                 if (endcodePos == -1 || endcodePos >= pos + len)
       
  1092                     break;
       
  1093                 result.remove(endcodePos + 1, 1);
       
  1094                 len -= 1;
       
  1095             }
       
  1096         }
       
  1097         pos += len + insertTagAround(result, pos, len, "@comment");
       
  1098     }
       
  1099 
       
  1100     return result;
       
  1101 }
       
  1102 
       
  1103 #ifdef QDOC_QML
       
  1104 /*!
       
  1105   This function is for documenting QML properties. It returns
       
  1106   the list of documentation sections for the children of the
       
  1107   \a qmlClassNode.
       
  1108 
       
  1109   Currently, it only handles QML property groups.
       
  1110  */
       
  1111 QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode,
       
  1112                                           SynopsisStyle style)
       
  1113 {
       
  1114     QList<Section> sections;
       
  1115     if (qmlClassNode) {
       
  1116         if (style == Summary) {
       
  1117 	    FastSection qmlproperties(qmlClassNode,
       
  1118                                       "Properties",
       
  1119                                       "property",
       
  1120                                       "properties");
       
  1121 	    FastSection qmlattachedproperties(qmlClassNode,
       
  1122                                               "Attached Properties",
       
  1123                                               "property",
       
  1124                                               "properties");
       
  1125 	    FastSection qmlsignals(qmlClassNode,
       
  1126                                 "Signals",
       
  1127                                 "signal",
       
  1128                                 "signals");
       
  1129 	    FastSection qmlattachedsignals(qmlClassNode,
       
  1130                                            "QML Attached Signals",
       
  1131                                            "signal",
       
  1132                                            "signals");
       
  1133 	    FastSection qmlmethods(qmlClassNode,
       
  1134                                    "Methods",
       
  1135                                    "method",
       
  1136                                    "methods");
       
  1137 	    FastSection qmlattachedmethods(qmlClassNode,
       
  1138                                            "QML Attached Methods",
       
  1139                                            "method",
       
  1140                                            "methods");
       
  1141 
       
  1142             NodeList::ConstIterator c = qmlClassNode->childNodes().begin();
       
  1143             while (c != qmlClassNode->childNodes().end()) {
       
  1144                 if ((*c)->subType() == Node::QmlPropertyGroup) {
       
  1145                     const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c);
       
  1146                     NodeList::ConstIterator p = qpgn->childNodes().begin();
       
  1147                     while (p != qpgn->childNodes().end()) {
       
  1148                         if ((*p)->type() == Node::QmlProperty) {
       
  1149                             const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*p);
       
  1150                             if (pn->isAttached())
       
  1151                                 insert(qmlattachedproperties,*p,style,Okay);
       
  1152                             else
       
  1153                                 insert(qmlproperties,*p,style,Okay);
       
  1154                         }
       
  1155                         ++p;
       
  1156                     }
       
  1157                 }
       
  1158                 else if ((*c)->type() == Node::QmlSignal) {
       
  1159                     const FunctionNode* sn = static_cast<const FunctionNode*>(*c);
       
  1160                     if (sn->isAttached())
       
  1161                         insert(qmlattachedsignals,*c,style,Okay);
       
  1162                     else
       
  1163                         insert(qmlsignals,*c,style,Okay);
       
  1164                 }
       
  1165                 else if ((*c)->type() == Node::QmlMethod) {
       
  1166                     const FunctionNode* mn = static_cast<const FunctionNode*>(*c);
       
  1167                     if (mn->isAttached())
       
  1168                         insert(qmlattachedmethods,*c,style,Okay);
       
  1169                     else
       
  1170                         insert(qmlmethods,*c,style,Okay);
       
  1171                 }
       
  1172                 ++c;
       
  1173             }
       
  1174 	    append(sections,qmlproperties);
       
  1175 	    append(sections,qmlattachedproperties);
       
  1176 	    append(sections,qmlsignals);
       
  1177 	    append(sections,qmlattachedsignals);
       
  1178 	    append(sections,qmlmethods);
       
  1179 	    append(sections,qmlattachedmethods);
       
  1180         }
       
  1181         else if (style == Detailed) {
       
  1182             FastSection qmlproperties(qmlClassNode, "Property Documentation");
       
  1183 	    FastSection qmlattachedproperties(qmlClassNode,"Attached Property Documentation");
       
  1184             FastSection qmlsignals(qmlClassNode,"Signal Documentation");
       
  1185 	    FastSection qmlattachedsignals(qmlClassNode,"Attached Signal Documentation");
       
  1186             FastSection qmlmethods(qmlClassNode,"Method Documentation");
       
  1187 	    FastSection qmlattachedmethods(qmlClassNode,"Attached Method Documentation");
       
  1188 	    NodeList::ConstIterator c = qmlClassNode->childNodes().begin();
       
  1189 	    while (c != qmlClassNode->childNodes().end()) {
       
  1190                 if ((*c)->subType() == Node::QmlPropertyGroup) {
       
  1191                     const QmlPropGroupNode* pgn = static_cast<const QmlPropGroupNode*>(*c);
       
  1192                     if (pgn->isAttached())
       
  1193                         insert(qmlattachedproperties,*c,style,Okay);
       
  1194                     else
       
  1195                         insert(qmlproperties,*c,style,Okay);
       
  1196 	        }
       
  1197                 else if ((*c)->type() == Node::QmlSignal) {
       
  1198                     const FunctionNode* sn = static_cast<const FunctionNode*>(*c);
       
  1199                     if (sn->isAttached())
       
  1200                         insert(qmlattachedsignals,*c,style,Okay);
       
  1201                     else
       
  1202                         insert(qmlsignals,*c,style,Okay);
       
  1203                 }
       
  1204                 else if ((*c)->type() == Node::QmlMethod) {
       
  1205                     const FunctionNode* mn = static_cast<const FunctionNode*>(*c);
       
  1206                     if (mn->isAttached())
       
  1207                         insert(qmlattachedmethods,*c,style,Okay);
       
  1208                     else
       
  1209                         insert(qmlmethods,*c,style,Okay);
       
  1210                 }
       
  1211 	        ++c;
       
  1212 	    }
       
  1213 	    append(sections,qmlproperties);
       
  1214 	    append(sections,qmlattachedproperties);
       
  1215 	    append(sections,qmlsignals);
       
  1216 	    append(sections,qmlattachedsignals);
       
  1217 	    append(sections,qmlmethods);
       
  1218 	    append(sections,qmlattachedmethods);
       
  1219         }
       
  1220     }
       
  1221 
       
  1222     return sections;
       
  1223 }
       
  1224 #endif
       
  1225 
       
  1226 QT_END_NAMESPACE