1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the tools applications of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
47 #include "cppcodemarker.h"
57 The constructor does nothing.
59 CppCodeMarker::CppCodeMarker()
65 The destructor does nothing.
67 CppCodeMarker::~CppCodeMarker()
75 bool CppCodeMarker::recognizeCode(const QString & /* code */)
81 Returns true if \a ext is any of a list of file extensions
84 bool CppCodeMarker::recognizeExtension(const QString& ext)
100 Returns true if \a lang is either "C" or "Cpp".
102 bool CppCodeMarker::recognizeLanguage(const QString &lang)
104 return lang == "C" || lang == "Cpp";
108 Returns the type of atom used to represent C++ code in the documentation.
110 Atom::Type CppCodeMarker::atomType() const
116 Returns the \a node name, or "()" if \a node is a
119 QString CppCodeMarker::plainName(const Node *node)
121 QString name = node->name();
122 if (node->type() == Node::Function)
127 QString CppCodeMarker::plainFullName(const Node *node, const Node *relative)
129 if (node->name().isEmpty()) {
135 fullName.prepend(plainName(node));
136 if (node->parent() == relative || node->parent()->name().isEmpty())
138 fullName.prepend("::");
139 node = node->parent();
145 QString CppCodeMarker::markedUpCode(const QString &code,
146 const Node *relative,
147 const Location &location)
149 return addMarkUp(code, relative, location);
152 QString CppCodeMarker::markedUpSynopsis(const Node *node,
153 const Node * /* relative */,
156 const int MaxEnumValues = 6;
157 const FunctionNode *func;
158 const PropertyNode *property;
159 const VariableNode *variable;
160 const EnumNode *enume;
161 const TypedefNode *typedeff;
166 name = taggedNode(node);
167 if (style != Detailed)
168 name = linkTag(node, name);
169 name = "<@name>" + name + "</@name>";
171 if (style == Detailed && !node->parent()->name().isEmpty() &&
172 node->type() != Node::Property)
173 name.prepend(taggedNode(node->parent()) + "::");
175 switch (node->type()) {
176 case Node::Namespace:
177 synopsis = "namespace " + name;
180 synopsis = "class " + name;
183 case Node::QmlSignal:
184 case Node::QmlMethod:
185 func = (const FunctionNode *) node;
186 if (style != SeparateList && !func->returnType().isEmpty())
187 synopsis = typified(func->returnType()) + " ";
189 if (func->metaness() != FunctionNode::MacroWithoutParams) {
191 if (!func->parameters().isEmpty()) {
193 QList<Parameter>::ConstIterator p = func->parameters().begin();
194 while (p != func->parameters().end()) {
195 if (p != func->parameters().begin())
197 synopsis += typified((*p).leftType());
198 if (style != SeparateList && !(*p).name().isEmpty())
200 " <@param>" + protect((*p).name()) + "</@param>";
201 synopsis += protect((*p).rightType());
202 if (style != SeparateList && !(*p).defaultValue().isEmpty())
203 synopsis += " = " + protect((*p).defaultValue());
211 synopsis += " const";
213 if (style == Summary || style == Accessors) {
214 if (func->virtualness() != FunctionNode::NonVirtual)
215 synopsis.prepend("virtual ");
216 if (func->virtualness() == FunctionNode::PureVirtual)
217 synopsis.append(" = 0");
219 else if (style == SeparateList) {
220 if (!func->returnType().isEmpty() && func->returnType() != "void")
221 synopsis += " : " + typified(func->returnType());
224 QStringList bracketed;
225 if (func->isStatic()) {
226 bracketed += "static";
228 else if (func->virtualness() != FunctionNode::NonVirtual) {
229 if (func->virtualness() == FunctionNode::PureVirtual)
231 bracketed += "virtual";
234 if (func->access() == Node::Protected) {
235 bracketed += "protected";
237 else if (func->access() == Node::Private) {
238 bracketed += "private";
241 if (func->metaness() == FunctionNode::Signal) {
242 bracketed += "signal";
244 else if (func->metaness() == FunctionNode::Slot) {
247 if (!bracketed.isEmpty())
248 extra += " [" + bracketed.join(" ") + "]";
252 enume = static_cast<const EnumNode *>(node);
253 synopsis = "enum " + name;
254 if (style == Summary) {
257 QStringList documentedItems = enume->doc().enumItemNames();
258 if (documentedItems.isEmpty()) {
259 foreach (const EnumItem &item, enume->items())
260 documentedItems << item.name();
262 QStringList omitItems = enume->doc().omitEnumItemNames();
263 foreach (const QString &item, omitItems)
264 documentedItems.removeAll(item);
266 if (documentedItems.size() <= MaxEnumValues) {
267 for (int i = 0; i < documentedItems.size(); ++i) {
270 synopsis += documentedItems.at(i);
274 for (int i = 0; i < documentedItems.size(); ++i) {
275 if (i < MaxEnumValues-2 || i == documentedItems.size()-1) {
278 synopsis += documentedItems.at(i);
280 else if (i == MaxEnumValues - 1) {
285 if (!documentedItems.isEmpty())
291 typedeff = static_cast<const TypedefNode *>(node);
292 if (typedeff->associatedEnum()) {
293 synopsis = "flags " + name;
296 synopsis = "typedef " + name;
300 property = static_cast<const PropertyNode *>(node);
301 synopsis = name + " : " + typified(property->qualifiedDataType());
304 variable = static_cast<const VariableNode *>(node);
305 if (style == SeparateList) {
306 synopsis = name + " : " + typified(variable->dataType());
309 synopsis = typified(variable->leftType()) + " " +
310 name + protect(variable->rightType());
317 if (style == Summary) {
318 if (node->status() == Node::Preliminary) {
319 extra += " (preliminary)";
321 else if (node->status() == Node::Deprecated) {
322 extra += " (deprecated)";
324 else if (node->status() == Node::Obsolete) {
325 extra += " (obsolete)";
329 if (!extra.isEmpty()) {
330 extra.prepend("<@extra>");
331 extra.append("</@extra>");
333 return synopsis + extra;
339 QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary)
341 QString name = taggedQmlNode(node);
343 name = linkTag(node,name);
344 } else if (node->type() == Node::QmlProperty) {
345 const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
346 if (pn->isAttached())
347 name.prepend(pn->element() + QLatin1Char('.'));
349 name = "<@name>" + name + "</@name>";
350 QString synopsis = name;
351 if (node->type() == Node::QmlProperty) {
352 const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
353 synopsis += " : " + typified(pn->dataType());
358 if (node->status() == Node::Preliminary) {
359 extra += " (preliminary)";
361 else if (node->status() == Node::Deprecated) {
362 extra += " (deprecated)";
364 else if (node->status() == Node::Obsolete) {
365 extra += " (obsolete)";
369 if (!extra.isEmpty()) {
370 extra.prepend("<@extra>");
371 extra.append("</@extra>");
373 return synopsis + extra;
377 QString CppCodeMarker::markedUpName(const Node *node)
379 QString name = linkTag(node, taggedNode(node));
380 if (node->type() == Node::Function)
385 QString CppCodeMarker::markedUpFullName(const Node *node, const Node *relative)
387 if (node->name().isEmpty()) {
393 fullName.prepend(markedUpName(node));
394 if (node->parent() == relative || node->parent()->name().isEmpty())
396 fullName.prepend("<@op>::</@op>");
397 node = node->parent();
403 QString CppCodeMarker::markedUpEnumValue(const QString &enumValue,
404 const Node *relative)
406 const Node *node = relative->parent();
408 while (node->parent()) {
409 fullName.prepend(markedUpName(node));
410 if (node->parent() == relative || node->parent()->name().isEmpty())
412 fullName.prepend("<@op>::</@op>");
413 node = node->parent();
415 if (!fullName.isEmpty())
416 fullName.append("<@op>::</@op>");
417 fullName.append(enumValue);
421 QString CppCodeMarker::markedUpIncludes(const QStringList& includes)
425 QStringList::ConstIterator inc = includes.begin();
426 while (inc != includes.end()) {
427 code += "<@preprocessor>#include <<@headerfile>" + *inc + "</@headerfile>></@preprocessor>\n";
433 QString CppCodeMarker::functionBeginRegExp(const QString& funcName)
435 return "^" + QRegExp::escape(funcName) + "$";
439 QString CppCodeMarker::functionEndRegExp(const QString& /* funcName */)
444 QList<Section> CppCodeMarker::sections(const InnerNode *inner,
448 QList<Section> sections;
450 if (inner->type() == Node::Class) {
451 const ClassNode *classe = static_cast<const ClassNode *>(inner);
453 if (style == Summary) {
454 FastSection privateFunctions(classe,
458 "private functions");
459 FastSection privateSlots(classe, "Private Slots", "", "private slot", "private slots");
460 FastSection privateTypes(classe, "Private Types", "", "private type", "private types");
461 FastSection protectedFunctions(classe,
462 "Protected Functions",
464 "protected function",
465 "protected functions");
466 FastSection protectedSlots(classe,
471 FastSection protectedTypes(classe,
476 FastSection protectedVariables(classe,
477 "Protected Variables",
480 "protected variables");
481 FastSection publicFunctions(classe,
486 FastSection publicSignals(classe, "Signals", "", "signal", "signals");
487 FastSection publicSlots(classe, "Public Slots", "", "public slot", "public slots");
488 FastSection publicTypes(classe, "Public Types", "", "public type", "public types");
489 FastSection publicVariables(classe,
494 FastSection properties(classe, "Properties", "", "property", "properties");
495 FastSection relatedNonMembers(classe,
496 "Related Non-Members",
498 "related non-member",
499 "related non-members");
500 FastSection staticPrivateMembers(classe,
501 "Static Private Members",
503 "static private member",
504 "static private members");
505 FastSection staticProtectedMembers(classe,
506 "Static Protected Members",
508 "static protected member",
509 "static protected members");
510 FastSection staticPublicMembers(classe,
511 "Static Public Members",
513 "static public member",
514 "static public members");
515 FastSection macros(inner, "Macros", "", "macro", "macros");
517 NodeList::ConstIterator r = classe->relatedNodes().begin();
518 while (r != classe->relatedNodes().end()) {
519 if ((*r)->type() == Node::Function) {
520 FunctionNode *func = static_cast<FunctionNode *>(*r);
522 insert(macros, *r, style, status);
524 insert(relatedNonMembers, *r, style, status);
527 insert(relatedNonMembers, *r, style, status);
532 QStack<const ClassNode *> stack;
535 while (!stack.isEmpty()) {
536 const ClassNode *ancestorClass = stack.pop();
538 NodeList::ConstIterator c = ancestorClass->childNodes().begin();
539 while (c != ancestorClass->childNodes().end()) {
541 bool isSignal = false;
542 bool isStatic = false;
543 if ((*c)->type() == Node::Function) {
544 const FunctionNode *func = (const FunctionNode *) *c;
545 isSlot = (func->metaness() == FunctionNode::Slot);
546 isSignal = (func->metaness() == FunctionNode::Signal);
547 isStatic = func->isStatic();
549 else if ((*c)->type() == Node::Variable) {
550 const VariableNode *var = static_cast<const VariableNode *>(*c);
551 isStatic = var->isStatic();
554 switch ((*c)->access()) {
557 insert(publicSlots, *c, style, status);
560 insert(publicSignals, *c, style, status);
563 if ((*c)->type() != Node::Variable
564 || !(*c)->doc().isEmpty())
565 insert(staticPublicMembers,*c,style,status);
567 else if ((*c)->type() == Node::Property) {
568 insert(properties, *c, style, status);
570 else if ((*c)->type() == Node::Variable) {
571 if (!(*c)->doc().isEmpty())
572 insert(publicVariables, *c, style, status);
574 else if ((*c)->type() == Node::Function) {
575 if (!insertReimpFunc(publicFunctions,*c,status))
576 insert(publicFunctions, *c, style, status);
579 insert(publicTypes, *c, style, status);
582 case Node::Protected:
584 insert(protectedSlots, *c, style, status);
587 if ((*c)->type() != Node::Variable
588 || !(*c)->doc().isEmpty())
589 insert(staticProtectedMembers,*c,style,status);
591 else if ((*c)->type() == Node::Variable) {
592 if (!(*c)->doc().isEmpty())
593 insert(protectedVariables,*c,style,status);
595 else if ((*c)->type() == Node::Function) {
596 if (!insertReimpFunc(protectedFunctions,*c,status))
597 insert(protectedFunctions, *c, style, status);
600 insert(protectedTypes, *c, style, status);
605 insert(privateSlots, *c, style, status);
608 if ((*c)->type() != Node::Variable
609 || !(*c)->doc().isEmpty())
610 insert(staticPrivateMembers,*c,style,status);
612 else if ((*c)->type() == Node::Function) {
613 if (!insertReimpFunc(privateFunctions,*c,status))
614 insert(privateFunctions, *c, style, status);
617 insert(privateTypes,*c,style,status);
623 QList<RelatedClass>::ConstIterator r =
624 ancestorClass->baseClasses().begin();
625 while (r != ancestorClass->baseClasses().end()) {
626 stack.prepend((*r).node);
631 append(sections, publicTypes);
632 append(sections, properties);
633 append(sections, publicFunctions);
634 append(sections, publicSlots);
635 append(sections, publicSignals);
636 append(sections, publicVariables);
637 append(sections, staticPublicMembers);
638 append(sections, protectedTypes);
639 append(sections, protectedFunctions);
640 append(sections, protectedSlots);
641 append(sections, protectedVariables);
642 append(sections, staticProtectedMembers);
643 append(sections, privateTypes);
644 append(sections, privateFunctions);
645 append(sections, privateSlots);
646 append(sections, staticPrivateMembers);
647 append(sections, relatedNonMembers);
648 append(sections, macros);
650 else if (style == Detailed) {
651 FastSection memberFunctions(classe,"Member Function Documentation","func","member","members");
652 FastSection memberTypes(classe,"Member Type Documentation","types","member","members");
653 FastSection memberVariables(classe,"Member Variable Documentation","vars","member","members");
654 FastSection properties(classe,"Property Documentation","prop","member","members");
655 FastSection relatedNonMembers(classe,"Related Non-Members","relnonmem","member","members");
656 FastSection macros(classe,"Macro Documentation","macros","member","members");
658 NodeList::ConstIterator r = classe->relatedNodes().begin();
659 while (r != classe->relatedNodes().end()) {
660 if ((*r)->type() == Node::Function) {
661 FunctionNode *func = static_cast<FunctionNode *>(*r);
663 insert(macros, *r, style, status);
665 insert(relatedNonMembers, *r, style, status);
668 insert(relatedNonMembers, *r, style, status);
673 NodeList::ConstIterator c = classe->childNodes().begin();
674 while (c != classe->childNodes().end()) {
675 if ((*c)->type() == Node::Enum ||
676 (*c)->type() == Node::Typedef) {
677 insert(memberTypes, *c, style, status);
679 else if ((*c)->type() == Node::Property) {
680 insert(properties, *c, style, status);
682 else if ((*c)->type() == Node::Variable) {
683 if (!(*c)->doc().isEmpty())
684 insert(memberVariables, *c, style, status);
686 else if ((*c)->type() == Node::Function) {
687 FunctionNode *function = static_cast<FunctionNode *>(*c);
688 if (!function->associatedProperty())
689 insert(memberFunctions, function, style, status);
694 append(sections, memberTypes);
695 append(sections, properties);
696 append(sections, memberFunctions);
697 append(sections, memberVariables);
698 append(sections, relatedNonMembers);
699 append(sections, macros);
702 FastSection all(classe,"","","member","members");
704 QStack<const ClassNode *> stack;
707 while (!stack.isEmpty()) {
708 const ClassNode *ancestorClass = stack.pop();
710 NodeList::ConstIterator c = ancestorClass->childNodes().begin();
711 while (c != ancestorClass->childNodes().end()) {
712 if ((*c)->access() != Node::Private &&
713 (*c)->type() != Node::Property)
714 insert(all, *c, style, status);
718 QList<RelatedClass>::ConstIterator r =
719 ancestorClass->baseClasses().begin();
720 while (r != ancestorClass->baseClasses().end()) {
721 stack.prepend((*r).node);
725 append(sections, all);
729 if (style == Summary || style == Detailed) {
730 FastSection namespaces(inner,
732 style == Detailed ? "nmspace" : "",
735 FastSection classes(inner,
737 style == Detailed ? "classes" : "",
740 FastSection types(inner,
741 style == Summary ? "Types" : "Type Documentation",
742 style == Detailed ? "types" : "",
745 FastSection functions(inner,
747 "Functions" : "Function Documentation",
748 style == Detailed ? "func" : "",
751 FastSection macros(inner,
753 "Macros" : "Macro Documentation",
754 style == Detailed ? "macros" : "",
758 NodeList nodeList = inner->childNodes();
759 nodeList += inner->relatedNodes();
761 NodeList::ConstIterator n = nodeList.begin();
762 while (n != nodeList.end()) {
763 switch ((*n)->type()) {
764 case Node::Namespace:
765 insert(namespaces, *n, style, status);
768 insert(classes, *n, style, status);
772 insert(types, *n, style, status);
776 FunctionNode *func = static_cast<FunctionNode *>(*n);
778 insert(macros, *n, style, status);
780 insert(functions, *n, style, status);
788 append(sections, namespaces);
789 append(sections, classes);
790 append(sections, types);
791 append(sections, functions);
792 append(sections, macros);
799 const Node *CppCodeMarker::resolveTarget(const QString& target,
801 const Node* relative,
804 if (target.endsWith("()")) {
805 const FunctionNode *func;
806 QString funcName = target;
809 QStringList path = funcName.split("::");
810 if ((func = tree->findFunctionNode(path,
812 Tree::SearchBaseClasses))
813 && func->metaness() != FunctionNode::MacroWithoutParams)
816 else if (target.contains("#")) {
817 // ### this doesn't belong here; get rid of TargetNode hack
818 int hashAt = target.indexOf("#");
819 QString link = target.left(hashAt);
820 QString ref = target.mid(hashAt + 1);
822 if (link.isEmpty()) {
826 QStringList path(link);
827 node = tree->findNode(path, tree->root(), Tree::SearchBaseClasses);
829 if (node && node->isInnerNode()) {
830 const Atom *atom = node->doc().body().firstAtom();
832 if (atom->type() == Atom::Target && atom->string() == ref) {
833 Node *parentNode = const_cast<Node *>(node);
834 return new TargetNode(static_cast<InnerNode*>(parentNode),
842 QStringList path = target.split("::");
844 int flags = Tree::SearchBaseClasses |
845 Tree::SearchEnumValues |
847 if ((node = tree->findNode(path,
856 static const char * const typeTable[] = {
857 "bool", "char", "double", "float", "int", "long", "short",
858 "signed", "unsigned", "uint", "ulong", "ushort", "uchar", "void",
859 "qlonglong", "qulonglong",
860 "qint", "qint8", "qint16", "qint32", "qint64",
861 "quint", "quint8", "quint16", "quint32", "quint64",
865 static const char * const keywordTable[] = {
866 "and", "and_eq", "asm", "auto", "bitand", "bitor", "break",
867 "case", "catch", "class", "compl", "const", "const_cast",
868 "continue", "default", "delete", "do", "dynamic_cast", "else",
869 "enum", "explicit", "export", "extern", "false", "for", "friend",
870 "goto", "if", "include", "inline", "monitor", "mutable", "namespace",
871 "new", "not", "not_eq", "operator", "or", "or_eq", "private", "protected",
872 "public", "register", "reinterpret_cast", "return", "sizeof",
873 "static", "static_cast", "struct", "switch", "template", "this",
874 "throw", "true", "try", "typedef", "typeid", "typename", "union",
875 "using", "virtual", "volatile", "wchar_t", "while", "xor",
876 "xor_eq", "synchronized",
878 "signals", "slots", "emit", 0
894 QString CppCodeMarker::addMarkUp(const QString &in,
895 const Node * /* relative */,
896 const Location & /* location */)
899 ch = (i < (int)code.length()) ? code[i++].cell() : EOF
903 QMap<QString, int> types;
904 QMap<QString, int> keywords;
906 while (typeTable[j] != 0) {
907 types.insert(QString(typeTable[j]), 0);
911 while (keywordTable[j] != 0) {
912 keywords.insert(QString(keywordTable[j]), 0);
923 QRegExp classRegExp("Qt?(?:[A-Z3]+[a-z][A-Za-z]*|t)");
924 QRegExp functionRegExp("q([A-Z][a-z]+)+");
932 if (ch.isLetter() || ch == '_') {
938 } while (ch.isLetterOrNumber() || ch == '_');
940 if (classRegExp.exactMatch(ident)) {
941 tag = QLatin1String("type");
942 } else if (functionRegExp.exactMatch(ident)) {
943 tag = QLatin1String("func");
945 } else if (types.contains(ident)) {
946 tag = QLatin1String("type");
947 } else if (keywords.contains(ident)) {
948 tag = QLatin1String("keyword");
949 } else if (braceDepth == 0 && parenDepth == 0) {
950 if (QString(code.unicode() + i - 1, code.length() - (i - 1))
951 .indexOf(QRegExp(QLatin1String("^\\s*\\("))) == 0)
952 tag = QLatin1String("func");
955 } else if (ch.isDigit()) {
959 } while (ch.isLetterOrNumber() || ch == '.');
960 tag = QLatin1String("number");
962 switch (ch.unicode()) {
982 tag = QLatin1String("op");
988 while (ch != EOF && ch != '"') {
995 tag = QLatin1String("string");
1000 while (ch != EOF && ch != '\n') {
1006 tag = QLatin1String("preprocessor");
1012 while (ch != EOF && ch != '\'') {
1019 tag = QLatin1String("char");
1037 tag = QLatin1String("op");
1047 } while (ch != EOF && ch != '\n');
1048 tag = QLatin1String("comment");
1049 } else if (ch == '*') {
1050 bool metAster = false;
1051 bool metAsterSlash = false;
1056 while (!metAsterSlash) {
1062 else if (metAster && ch == '/')
1063 metAsterSlash = true;
1069 tag = QLatin1String("comment");
1071 tag = QLatin1String("op");
1091 text = code.mid(start, finish - start);
1094 if (!tag.isEmpty()) {
1095 out += QLatin1String("<@") + tag;
1097 out += QLatin1String(" target=\"") + text + QLatin1String("()\"");
1098 out += QLatin1String(">");
1101 out += protect(text);
1104 out += QLatin1String("</@") + tag + QLatin1String(">");
1107 if (start < code.length()) {
1108 out += protect(code.mid(start));
1116 This function is for documenting QML properties. It returns
1117 the list of documentation sections for the children of the
1120 Currently, it only handles QML property groups.
1122 QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode,
1123 SynopsisStyle style,
1126 QList<Section> sections;
1128 if (style == Summary) {
1129 FastSection qmlproperties(qmlClassNode,
1134 FastSection qmlattachedproperties(qmlClassNode,
1135 "Attached Properties",
1139 FastSection qmlsignals(qmlClassNode,
1144 FastSection qmlattachedsignals(qmlClassNode,
1145 "Attached Signal Handlers",
1149 FastSection qmlmethods(qmlClassNode,
1154 FastSection qmlattachedmethods(qmlClassNode,
1160 NodeList::ConstIterator c = qmlClassNode->childNodes().begin();
1161 while (c != qmlClassNode->childNodes().end()) {
1162 if ((*c)->subType() == Node::QmlPropertyGroup) {
1163 const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c);
1164 NodeList::ConstIterator p = qpgn->childNodes().begin();
1165 while (p != qpgn->childNodes().end()) {
1166 if ((*p)->type() == Node::QmlProperty) {
1167 const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*p);
1168 if (pn->isAttached())
1169 insert(qmlattachedproperties,*p,style,Okay);
1171 insert(qmlproperties,*p,style,Okay);
1176 else if ((*c)->type() == Node::QmlSignal) {
1177 const FunctionNode* sn = static_cast<const FunctionNode*>(*c);
1178 if (sn->isAttached())
1179 insert(qmlattachedsignals,*c,style,Okay);
1181 insert(qmlsignals,*c,style,Okay);
1183 else if ((*c)->type() == Node::QmlMethod) {
1184 const FunctionNode* mn = static_cast<const FunctionNode*>(*c);
1185 if (mn->isAttached())
1186 insert(qmlattachedmethods,*c,style,Okay);
1188 insert(qmlmethods,*c,style,Okay);
1192 append(sections,qmlproperties);
1193 append(sections,qmlattachedproperties);
1194 append(sections,qmlsignals);
1195 append(sections,qmlattachedsignals);
1196 append(sections,qmlmethods);
1197 append(sections,qmlattachedmethods);
1199 else if (style == Detailed) {
1200 FastSection qmlproperties(qmlClassNode, "Property Documentation","qmlprop","member","members");
1201 FastSection qmlattachedproperties(qmlClassNode,"Attached Property Documentation","qmlattprop",
1202 "member","members");
1203 FastSection qmlsignals(qmlClassNode,"Signal Handler Documentation","qmlsig","handler","handlers");
1204 FastSection qmlattachedsignals(qmlClassNode,"Attached Signal Handler Documentation","qmlattsig",
1205 "handler","handlers");
1206 FastSection qmlmethods(qmlClassNode,"Method Documentation","qmlmeth","member","members");
1207 FastSection qmlattachedmethods(qmlClassNode,"Attached Method Documentation","qmlattmeth",
1208 "member","members");
1209 NodeList::ConstIterator c = qmlClassNode->childNodes().begin();
1210 while (c != qmlClassNode->childNodes().end()) {
1211 if ((*c)->subType() == Node::QmlPropertyGroup) {
1212 const QmlPropGroupNode* pgn = static_cast<const QmlPropGroupNode*>(*c);
1213 if (pgn->isAttached())
1214 insert(qmlattachedproperties,*c,style,Okay);
1216 insert(qmlproperties,*c,style,Okay);
1218 else if ((*c)->type() == Node::QmlSignal) {
1219 const FunctionNode* sn = static_cast<const FunctionNode*>(*c);
1220 if (sn->isAttached())
1221 insert(qmlattachedsignals,*c,style,Okay);
1223 insert(qmlsignals,*c,style,Okay);
1225 else if ((*c)->type() == Node::QmlMethod) {
1226 const FunctionNode* mn = static_cast<const FunctionNode*>(*c);
1227 if (mn->isAttached())
1228 insert(qmlattachedmethods,*c,style,Okay);
1230 insert(qmlmethods,*c,style,Okay);
1234 append(sections,qmlproperties);
1235 append(sections,qmlattachedproperties);
1236 append(sections,qmlsignals);
1237 append(sections,qmlattachedsignals);
1238 append(sections,qmlmethods);
1239 append(sections,qmlattachedmethods);
1242 FastSection all(qmlClassNode,"","","member","members");
1244 QStack<const QmlClassNode*> stack;
1245 stack.push(qmlClassNode);
1247 while (!stack.isEmpty()) {
1248 const QmlClassNode* ancestorClass = stack.pop();
1250 NodeList::ConstIterator c = ancestorClass->childNodes().begin();
1251 while (c != ancestorClass->childNodes().end()) {
1252 // if ((*c)->access() != Node::Private)
1253 if ((*c)->subType() == Node::QmlPropertyGroup) {
1254 const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c);
1255 NodeList::ConstIterator p = qpgn->childNodes().begin();
1256 while (p != qpgn->childNodes().end()) {
1257 if ((*p)->type() == Node::QmlProperty) {
1258 insert(all,*p,style,Okay);
1264 insert(all,*c,style,Okay);
1268 if (!ancestorClass->links().empty()) {
1269 if (ancestorClass->links().contains(Node::InheritsLink)) {
1270 QPair<QString,QString> linkPair;
1271 linkPair = ancestorClass->links()[Node::InheritsLink];
1272 QStringList strList(linkPair.first);
1273 const Node* n = tree->findNode(strList,Node::Fake);
1274 if (n && n->subType() == Node::QmlClass) {
1275 const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
1281 append(sections, all);