return QLatin1Char('/') + protect(myName);
}
else {
- return plainFullName(node) + QLatin1Char('/') + protect(myName);
+ return node->plainFullName() + QLatin1Char('/') + protect(myName);
}
}
/*!
- Get the list of documentation sections for the children of
- the specified QmlClassNode.
+ Returns an empty list of documentation sections.
*/
-QList<Section> CodeMarker::qmlSections(const QmlClassNode* ,
- SynopsisStyle )
+QList<Section> CodeMarker::qmlSections(const QmlClassNode* , SynopsisStyle )
{
return QList<Section>();
}
-const Node* CodeMarker::resolveTarget(const QString& /* target */,
- const Tree* ,
- const Node* ,
- const Node* )
-{
- return 0;
-}
-
QT_END_NAMESPACE
virtual bool recognizeExtension(const QString& ext) = 0;
virtual bool recognizeLanguage(const QString& lang) = 0;
virtual Atom::Type atomType() const = 0;
- virtual QString plainName(const Node *node) = 0;
- virtual QString plainFullName(const Node *node,
- const Node *relative = 0) = 0;
virtual QString markedUpCode(const QString& code,
const Node *relative,
const Location &location) = 0;
virtual QList<Section> sections(const InnerNode *inner,
SynopsisStyle style,
Status status) = 0;
- virtual QList<Section> qmlSections(const QmlClassNode* qmlClassNode,
- SynopsisStyle style);
- virtual const Node* resolveTarget(const QString& target,
- const Tree* tree,
- const Node* relative,
- const Node* self = 0);
+ virtual QList<Section> qmlSections(const QmlClassNode* qmlClassNode, SynopsisStyle style);
virtual QStringList macRefsForNode(Node* node);
static void initialize(const Config& config);
#include "tree.h"
#include "config.h"
#include "generator.h"
+#include "qdocdatabase.h"
#include <qdebug.h>
QT_BEGIN_NAMESPACE
*/
CodeParser::CodeParser()
{
+ qdb_ = QDocDatabase::qdocDB();
parsers.prepend(this);
}
return sourceFileNameFilter();
}
-void CodeParser::parseHeaderFile(const Location& location,
- const QString& filePath,
- Tree *tree)
+void CodeParser::parseHeaderFile(const Location& location, const QString& filePath)
{
- parseSourceFile(location, filePath, tree);
+ parseSourceFile(location, filePath);
}
-void CodeParser::doneParsingHeaderFiles(Tree *tree)
+void CodeParser::doneParsingHeaderFiles()
{
- doneParsingSourceFiles(tree);
+ doneParsingSourceFiles();
}
/*!
void CodeParser::processCommonMetaCommand(const Location& location,
const QString& command,
const ArgLocPair& arg,
- Node* node,
- Tree* tree)
+ Node* node)
{
if (command == COMMAND_COMPAT) {
location.warning(tr("\\compat command used, but Qt3 compatibility is no longer supported"));
node->setStatus(Node::Deprecated);
}
else if (command == COMMAND_INGROUP) {
- tree->addToGroup(node, arg.first);
+ qdb_->addToGroup(node, arg.first);
}
else if (command == COMMAND_INPUBLICGROUP) {
- tree->addToPublicGroup(node, arg.first);
+ qdb_->addToPublicGroup(node, arg.first);
}
else if (command == COMMAND_INMODULE) {
- node->setModuleName(arg.first);
+ qdb_->addToModule(arg.first,node);
}
else if (command == COMMAND_INQMLMODULE) {
- node->setQmlModule(arg);
- DocNode* fn = DocNode::lookupQmlModuleNode(tree, arg);
- fn->addQmlModuleMember(node);
- QString qmid = node->qmlModuleIdentifier();
- QmlClassNode* qcn = static_cast<QmlClassNode*>(node);
- QmlClassNode::insertQmlModuleMember(qmid, qcn);
+ qdb_->addToQmlModule(arg.first,node);
}
else if (command == COMMAND_MAINCLASS) {
node->setStatus(Node::Main);
**
****************************************************************************/
-/*
- codeparser.h
-*/
-
#ifndef CODEPARSER_H
#define CODEPARSER_H
#include <QSet>
-
#include "node.h"
QT_BEGIN_NAMESPACE
class Config;
class Node;
class QString;
-class Tree;
+class QDocDatabase;
class CodeParser
{
virtual QString language() = 0;
virtual QStringList headerFileNameFilter();
virtual QStringList sourceFileNameFilter() = 0;
- virtual void parseHeaderFile(const Location& location,
- const QString& filePath, Tree *tree);
- virtual void parseSourceFile(const Location& location,
- const QString& filePath, Tree *tree) = 0;
- virtual void doneParsingHeaderFiles(Tree *tree);
- virtual void doneParsingSourceFiles(Tree *tree) = 0;
+ virtual void parseHeaderFile(const Location& location, const QString& filePath);
+ virtual void parseSourceFile(const Location& location, const QString& filePath) = 0;
+ virtual void doneParsingHeaderFiles();
+ virtual void doneParsingSourceFiles() = 0;
bool isParsingH() const;
bool isParsingCpp() const;
void processCommonMetaCommand(const Location& location,
const QString& command,
const ArgLocPair& arg,
- Node *node, Tree *tree);
+ Node *node);
static void extractPageLinkAndDesc(const QString& arg,
QString* link,
QString* desc);
QString currentFile_;
+ QDocDatabase* qdb_;
private:
static QString currentSubDir_;
return Atom::Code;
}
-/*!
- Returns the \a node name, or "()" if \a node is a
- Node::Function node.
- */
-QString CppCodeMarker::plainName(const Node *node)
-{
- QString name = node->name();
- if (node->type() == Node::Function)
- name += QLatin1String("()");
- return name;
-}
-
-QString CppCodeMarker::plainFullName(const Node *node, const Node *relative)
-{
- if (node->name().isEmpty()) {
- return QLatin1String("global");
- }
- else {
- QString fullName;
- while (node) {
- fullName.prepend(plainName(node));
- if (node->parent() == relative ||
- node->parent()->subType() == Node::Collision ||
- node->parent()->name().isEmpty())
- break;
- fullName.prepend(QLatin1String("::"));
- node = node->parent();
- }
- return fullName;
- }
-}
-
QString CppCodeMarker::markedUpCode(const QString &code,
const Node *relative,
const Location &location)
return sections;
}
-/*!
- Search the \a tree for a node named \a target
- */
-const Node *CppCodeMarker::resolveTarget(const QString& target,
- const Tree* tree,
- const Node* relative,
- const Node* self)
-{
- const Node* node = 0;
- if (target.endsWith("()")) {
- QString funcName = target;
- funcName.chop(2);
- QStringList path = funcName.split("::");
- const FunctionNode* fn = tree->findFunctionNode(path, relative, Tree::SearchBaseClasses);
- if (fn) {
- /*
- Why is this case not accepted?
- */
- if (fn->metaness() != FunctionNode::MacroWithoutParams)
- node = fn;
- }
- }
- else if (target.contains(QLatin1Char('#'))) {
- // This error message is never printed; I think we can remove the case.
- qDebug() << "qdoc: target case not handled:" << target;
- }
- else {
- QStringList path = target.split("::");
- int flags = Tree::SearchBaseClasses | Tree::SearchEnumValues | Tree::NonFunction;
- node = tree->findNode(path, relative, flags, self);
- }
- return node;
-}
-
static const char * const typeTable[] = {
"bool", "char", "double", "float", "int", "long", "short",
"signed", "unsigned", "uint", "ulong", "ushort", "uchar", "void",
virtual bool recognizeExtension(const QString& ext);
virtual bool recognizeLanguage(const QString& lang);
virtual Atom::Type atomType() const;
- virtual QString plainName(const Node *node);
- virtual QString plainFullName(const Node *node, const Node *relative);
virtual QString markedUpCode(const QString& code,
const Node *relative,
const Location &location);
virtual QList<Section> sections(const InnerNode *innerNode,
SynopsisStyle style,
Status status);
- virtual QList<Section> qmlSections(const QmlClassNode* qmlClassNode,
- SynopsisStyle style);
- virtual const Node* resolveTarget(const QString& target,
- const Tree* tree,
- const Node* relative,
- const Node* self = 0);
+ virtual QList<Section> qmlSections(const QmlClassNode* qmlClassNode, SynopsisStyle style);
private:
QString addMarkUp(const QString& protectedCode,
#include "config.h"
#include "cppcodeparser.h"
#include "tokenizer.h"
-#include "tree.h"
+#include "qdocdatabase.h"
#include <qdebug.h>
QT_BEGIN_NAMESPACE
QStringList CppCodeParser::exampleFiles;
QStringList CppCodeParser::exampleDirs;
-/*
- This is used for fuzzy matching only, which in turn is only used
- for Qt Jambi.
-*/
-static QString cleanType(const QString &type, Tree* tree)
-{
- QString result = type;
- result.replace("qlonglong", "long long");
- result.replace("qulonglong", "unsigned long long");
- result.replace("qreal", "double");
- result.replace(QRegExp("\\bu(int|short|char|long)\\b"), "unsigned \\1");
- result.replace("QRgb", "unsigned int");
- result.replace(" >", ">");
- result.remove(" const[]");
- result.replace("QStringList<QString>", "QStringList");
- result.replace("qint8", "char");
- result.replace("qint16", "short");
- result.replace("qint32", "int");
- result.replace("qint64", "long long");
- result.replace("quint8", "unsigned char");
- result.replace("quint16", "unsigned short");
- result.replace("quint32", "unsigned int");
- result.replace("quint64", "unsigned long long");
-
- if (result.contains("QFlags")) {
- QRegExp regExp("QFlags<(((?:[^<>]+::)*)([^<>:]+))>");
- int pos = 0;
- while ((pos = result.indexOf(regExp, pos)) != -1) {
- // we assume that the path for the associated enum
- // is the same as for the flag typedef
- QStringList path = regExp.cap(2).split("::", QString::SkipEmptyParts);
- QStringList tmpPath = QStringList(path) << regExp.cap(3);
- EnumNode* en = tree->findEnumNode(tmpPath);
- if (en && en->flagsType()) {
- tmpPath = QStringList(path) << en->flagsType()->name();
- result.replace(pos, regExp.matchedLength(), tmpPath.join("::"));
- }
- ++pos;
- }
- }
- if (result.contains("::")) {
- // remove needless (and needful) class prefixes
- QRegExp regExp("[A-Za-z0-9_]+::");
- result.remove(regExp);
- }
- return result;
-}
-
/*!
The constructor initializes some regular expressions
and calls reset().
CppCodeParser::CppCodeParser()
: varComment("/\\*\\s*([a-zA-Z_0-9]+)\\s*\\*/"), sep("(?:<[^>]+>)?::")
{
- reset(0);
+ reset();
}
/*!
}
/*!
- Parse the C++ header file identified by \a filePath
- and add the parsed contents to the big \a tree. The
- \a location is used for reporting errors.
+ Parse the C++ header file identified by \a filePath and add
+ the parsed contents to the database. The \a location is used
+ for reporting errors.
*/
-void CppCodeParser::parseHeaderFile(const Location& location,
- const QString& filePath,
- Tree *tree)
+void CppCodeParser::parseHeaderFile(const Location& location, const QString& filePath)
{
QFile in(filePath);
currentFile_ = filePath;
}
createOutputSubdirectory(location, filePath);
- reset(tree);
+ reset();
Location fileLocation(filePath);
Tokenizer fileTokenizer(fileLocation, in);
tokenizer = &fileTokenizer;
readToken();
- matchDeclList(tree->root());
+ matchDeclList(qdb_->treeRoot());
if (!fileTokenizer.version().isEmpty())
- tree->setVersion(fileTokenizer.version());
+ qdb_->setVersion(fileTokenizer.version());
in.close();
if (fileLocation.fileName() == "qiterator.h")
/*!
Get ready to parse the C++ cpp file identified by \a filePath
- and add its parsed contents to the big \a tree. \a location is
+ and add its parsed contents to the database. \a location is
used for reporting errors.
Call matchDocsAndStuff() to do all the parsing and tree building.
*/
-void CppCodeParser::parseSourceFile(const Location& location,
- const QString& filePath,
- Tree *tree)
+void CppCodeParser::parseSourceFile(const Location& location, const QString& filePath)
{
QFile in(filePath);
currentFile_ = filePath;
}
createOutputSubdirectory(location, filePath);
- reset(tree);
+ reset();
Location fileLocation(filePath);
Tokenizer fileTokenizer(fileLocation, in);
tokenizer = &fileTokenizer;
inheritance links in the tree. But it also initializes a
bunch of stuff.
*/
-void CppCodeParser::doneParsingHeaderFiles(Tree *tree)
+void CppCodeParser::doneParsingHeaderFiles()
{
- tree->resolveInheritance();
+ qdb_->resolveInheritance();
QMapIterator<QString, QString> i(sequentialIteratorClasses);
while (i.hasNext()) {
i.next();
- instantiateIteratorMacro(i.key(),
- i.value(),
- sequentialIteratorDefinition,
- tree);
+ instantiateIteratorMacro(i.key(), i.value(), sequentialIteratorDefinition);
}
i = mutableSequentialIteratorClasses;
while (i.hasNext()) {
i.next();
- instantiateIteratorMacro(i.key(),
- i.value(),
- mutableSequentialIteratorDefinition,
- tree);
+ instantiateIteratorMacro(i.key(), i.value(), mutableSequentialIteratorDefinition);
}
i = associativeIteratorClasses;
while (i.hasNext()) {
i.next();
- instantiateIteratorMacro(i.key(),
- i.value(),
- associativeIteratorDefinition,
- tree);
+ instantiateIteratorMacro(i.key(), i.value(), associativeIteratorDefinition);
}
i = mutableAssociativeIteratorClasses;
while (i.hasNext()) {
i.next();
- instantiateIteratorMacro(i.key(),
- i.value(),
- mutableAssociativeIteratorDefinition,
- tree);
+ instantiateIteratorMacro(i.key(), i.value(), mutableAssociativeIteratorDefinition);
}
sequentialIteratorDefinition.clear();
mutableSequentialIteratorDefinition.clear();
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 tree.
+ do other housekeeping of the database.
*/
-void CppCodeParser::doneParsingSourceFiles(Tree *tree)
+void CppCodeParser::doneParsingSourceFiles()
{
- tree->root()->clearCurrentChildPointers();
- tree->root()->normalizeOverloads();
- tree->fixInheritance();
- tree->resolveProperties();
- tree->root()->makeUndocumentedChildrenInternal();
-}
-
-/*!
- This function searches the \a tree to find a FunctionNode
- for a function with the signature \a synopsis. If the
- \a relative node is provided, the search begins there. If
- \a fuzzy is true, base classes are searched. The function
- node is returned, if found.
- */
-const FunctionNode *CppCodeParser::findFunctionNode(const QString& synopsis,
- Tree *tree,
- Node *relative,
- bool fuzzy)
-{
- QStringList parentPath;
- FunctionNode *clone;
- FunctionNode *func = 0;
- int flags = fuzzy ? int(Tree::SearchBaseClasses) : 0;
-
- reset(tree);
- if (makeFunctionNode(synopsis, &parentPath, &clone)) {
- func = tree->findFunctionNode(parentPath, clone, relative, flags);
-
- /*
- This is necessary because Roberto's parser resolves typedefs.
- */
- if (!func && fuzzy) {
- func = tree_->findFunctionNode(parentPath +
- QStringList(clone->name()),
- relative,
- flags);
- if (!func && clone->name().contains('_')) {
- QStringList path = parentPath;
- path << clone->name().split('_');
- func = tree_->findFunctionNode(path, relative, flags);
- }
-
- if (func) {
- NodeList overloads = func->parent()->overloads(func->name());
- NodeList candidates;
- for (int i = 0; i < overloads.count(); ++i) {
- FunctionNode *overload = static_cast<FunctionNode *>(overloads.at(i));
- if (overload->status() != Node::Compat
- && overload->parameters().count() == clone->parameters().count()
- && !overload->isConst() == !clone->isConst())
- candidates << overload;
- }
- if (candidates.count() == 0)
- return 0;
-
- /*
- There's only one function with the correct number
- of parameters. That must be the one.
- */
- if (candidates.count() == 1)
- return static_cast<FunctionNode *>(candidates.first());
-
- overloads = candidates;
- candidates.clear();
- for (int i = 0; i < overloads.count(); ++i) {
- FunctionNode *overload = static_cast<FunctionNode *>(overloads.at(i));
- QList<Parameter> params1 = overload->parameters();
- QList<Parameter> params2 = clone->parameters();
-
- int j;
- for (j = 0; j < params1.count(); ++j) {
- if (!params2.at(j).name().startsWith(params1.at(j).name()))
- break;
- }
- if (j == params1.count())
- candidates << overload;
- }
-
- /*
- There are several functions with the correct
- parameter count, but only one has the correct
- parameter names.
- */
- if (candidates.count() == 1)
- return static_cast<FunctionNode *>(candidates.first());
-
- candidates.clear();
- for (int i = 0; i < overloads.count(); ++i) {
- FunctionNode *overload = static_cast<FunctionNode *>(overloads.at(i));
- QList<Parameter> params1 = overload->parameters();
- QList<Parameter> params2 = clone->parameters();
-
- int j;
- for (j = 0; j < params1.count(); ++j) {
- if (params1.at(j).rightType() != params2.at(j).rightType())
- break;
-
- if (cleanType(params1.at(j).leftType(), tree)
- != cleanType(params2.at(j).leftType(), tree))
- break;
- }
- if (j == params1.count())
- candidates << overload;
- }
-
-
- /*
- There are several functions with the correct
- parameter count, but only one has the correct
- types, loosely compared.
- */
- if (candidates.count() == 1)
- return static_cast<FunctionNode *>(candidates.first());
-
- return 0;
- }
- }
- delete clone;
- }
- return func;
+ qdb_->treeRoot()->clearCurrentChildPointers();
+ qdb_->treeRoot()->normalizeOverloads();
+ qdb_->fixInheritance();
+ qdb_->resolveProperties();
+ qdb_->treeRoot()->makeUndocumentedChildrenInternal();
}
/*!
if (!activeNamespaces_.isEmpty()) {
foreach (const QString& usedNamespace_, activeNamespaces_) {
QStringList newPath = usedNamespace_.split("::") + parentPath;
- func = tree_->findFunctionNode(newPath, clone);
+ func = qdb_->findFunctionNode(newPath, clone);
if (func)
break;
}
}
// Search the root namespace if no match was found.
if (func == 0)
- func = tree_->findFunctionNode(parentPath, clone);
+ func = qdb_->findFunctionNode(parentPath, clone);
if (func == 0) {
- if (parentPath.isEmpty() && !lastPath.isEmpty())
- func = tree_->findFunctionNode(lastPath, clone);
+ if (parentPath.isEmpty() && !lastPath_.isEmpty())
+ func = qdb_->findFunctionNode(lastPath_, clone);
if (func == 0) {
doc.location().warning(tr("Cannot find '%1' in '\\%2' %3")
.arg(clone->name() + "(...)")
}
else {
doc.location().warning(tr("Missing '%1::' for '%2' in '\\%3'")
- .arg(lastPath.join("::"))
+ .arg(lastPath_.join("::"))
.arg(clone->name() + "()")
.arg(COMMAND_FN));
}
}
else {
- lastPath = parentPath;
+ lastPath_ = parentPath;
}
if (func) {
func->borrowParameterNames(clone);
QStringList parentPath;
FunctionNode *func = 0;
- if (makeFunctionNode(arg.first, &parentPath, &func, tree_->root())) {
+ if (makeFunctionNode(arg.first, &parentPath, &func, qdb_->treeRoot())) {
if (!parentPath.isEmpty()) {
doc.startLocation().warning(tr("Invalid syntax in '\\%1'").arg(COMMAND_MACRO));
delete func;
return func;
}
else if (QRegExp("[A-Za-z_][A-Za-z0-9_]+").exactMatch(arg.first)) {
- func = new FunctionNode(tree_->root(), arg.first);
+ func = new FunctionNode(qdb_->treeRoot(), arg.first);
func->setAccess(Node::Public);
func->setLocation(doc.startLocation());
func->setMetaness(FunctionNode::MacroWithoutParams);
if (!activeNamespaces_.isEmpty()) {
foreach (const QString& usedNamespace_, activeNamespaces_) {
QStringList newPath = usedNamespace_.split("::") + path;
- node = tree_->findNodeByNameAndType(newPath, type, subtype, 0);
+ node = qdb_->findNodeByNameAndType(newPath, type, subtype);
if (node) {
path = newPath;
break;
for it in the root namespace.
*/
if (node == 0) {
- node = tree_->findNodeByNameAndType(path, type, subtype, 0);
+ node = qdb_->findNodeByNameAndType(path, type, subtype);
}
if (node == 0) {
doc.location().warning(tr("Cannot find '%1' specified with '\\%2' in any header file")
.arg(arg.first).arg(command));
- lastPath = path;
+ lastPath_ = path;
}
else if (node->isInnerNode()) {
}
else if (command == COMMAND_EXAMPLE) {
if (Config::generateExamples) {
- ExampleNode* en = new ExampleNode(tree_->root(), arg.first);
+ ExampleNode* en = new ExampleNode(qdb_->treeRoot(), arg.first);
en->setLocation(doc.startLocation());
createExampleFileNodes(en);
return en;
}
}
else if (command == COMMAND_EXTERNALPAGE) {
- DocNode* dn = new DocNode(tree_->root(), arg.first, Node::ExternalPage, Node::ArticlePage);
+ DocNode* dn = new DocNode(qdb_->treeRoot(), arg.first, Node::ExternalPage, Node::ArticlePage);
dn->setLocation(doc.startLocation());
return dn;
}
else if (command == COMMAND_FILE) {
- DocNode* dn = new DocNode(tree_->root(), arg.first, Node::File, Node::NoPageType);
+ DocNode* dn = new DocNode(qdb_->treeRoot(), arg.first, Node::File, Node::NoPageType);
dn->setLocation(doc.startLocation());
return dn;
}
else if (command == COMMAND_GROUP) {
- DocNode* dn = new DocNode(tree_->root(), arg.first, Node::Group, Node::OverviewPage);
+ DocNode* dn = new DocNode(qdb_->treeRoot(), arg.first, Node::Group, Node::OverviewPage);
dn->setLocation(doc.startLocation());
return dn;
}
else if (command == COMMAND_HEADERFILE) {
- DocNode* dn = new DocNode(tree_->root(), arg.first, Node::HeaderFile, Node::ApiPage);
+ DocNode* dn = new DocNode(qdb_->treeRoot(), arg.first, Node::HeaderFile, Node::ApiPage);
dn->setLocation(doc.startLocation());
return dn;
}
else if (command == COMMAND_MODULE) {
- DocNode* dn = new DocNode(tree_->root(), arg.first, Node::Module, Node::OverviewPage);
+ DocNode* dn = qdb_->addModule(arg.first);
+ //DocNode* dn = new DocNode(qdb_->treeRoot(), arg.first, Node::Module, Node::OverviewPage);
dn->setLocation(doc.startLocation());
return dn;
}
else if (command == COMMAND_QMLMODULE) {
- DocNode* dn = DocNode::lookupQmlModuleNode(tree_, arg);
+ DocNode* dn = qdb_->addQmlModule(arg.first);
+ //DocNode* dn = DocNode::lookupQmlModuleNode(qdb_->tree(), arg);
dn->setLocation(doc.startLocation());
return dn;
}
If there is no collision, just create a new Page
node and return that one.
*/
- NameCollisionNode* ncn = tree_->checkForCollision(args[0]);
+ NameCollisionNode* ncn = qdb_->checkForCollision(args[0]);
DocNode* dn = 0;
if (ptype == Node::DitaMapPage)
- dn = new DitaMapNode(tree_->root(), args[0]);
+ dn = new DitaMapNode(qdb_->treeRoot(), args[0]);
else
- dn = new DocNode(tree_->root(), args[0], Node::Page, ptype);
+ dn = new DocNode(qdb_->treeRoot(), args[0], Node::Page, ptype);
dn->setLocation(doc.startLocation());
if (ncn) {
ncn->addCollision(dn);
return dn;
}
else if (command == COMMAND_DITAMAP) {
- DocNode* dn = new DitaMapNode(tree_->root(), arg.first);
+ DocNode* dn = new DitaMapNode(qdb_->treeRoot(), arg.first);
dn->setLocation(doc.startLocation());
return dn;
}
QML in a .qdoc file.
*/
if (names[1] != "0")
- classNode = tree_->findClassNode(names[1].split("::"));
+ classNode = qdb_->findClassNode(names[1].split("::"));
}
/*
If there is no collision, just create a new QML class
node and return that one.
*/
- NameCollisionNode* ncn = tree_->checkForCollision(names[0]);
- QmlClassNode* qcn = new QmlClassNode(tree_->root(), names[0]);
+ NameCollisionNode* ncn = qdb_->checkForCollision(names[0]);
+ QmlClassNode* qcn = new QmlClassNode(qdb_->treeRoot(), names[0]);
qcn->setClassNode(classNode);
qcn->setLocation(doc.startLocation());
#if 0
return qcn;
}
else if (command == COMMAND_QMLBASICTYPE) {
- QmlBasicTypeNode* n = new QmlBasicTypeNode(tree_->root(), arg.first);
+ QmlBasicTypeNode* n = new QmlBasicTypeNode(qdb_->treeRoot(), arg.first);
n->setLocation(doc.startLocation());
return n;
}
QString element;
QString type;
if (splitQmlMethodArg(arg.first,type,module,element)) {
- QmlClassNode* qmlClass = tree_->findQmlClassNode(module,element);
+ QmlClassNode* qmlClass = qdb_->findQmlType(module,element);
if (qmlClass) {
bool attached = false;
Node::Type nodeType = Node::QmlMethod;
ArgList::ConstIterator argsIter = args.constBegin();
arg = argsIter->first;
if (splitQmlPropertyArg(arg,type,module,element,property)) {
- qmlClass = tree_->findQmlClassNode(module,element);
+ qmlClass = qdb_->findQmlType(module,element);
if (qmlClass) {
qmlPropGroup = new QmlPropGroupNode(qmlClass,property); //,attached);
qmlPropGroup->setLocation(doc.startLocation());
/*
It should be a header file, I think.
*/
- n = tree_->findNodeByNameAndType(QStringList(arg), Node::Document, Node::NoSubType, 0);
+ n = qdb_->findNodeByNameAndType(QStringList(arg), Node::Document, Node::NoSubType);
}
else {
/*
If it wasn't a file, it should be either a class or a namespace.
*/
QStringList newPath = arg.split("::");
- n = tree_->findClassNode(newPath);
+ n = qdb_->findClassNode(newPath);
if (!n)
- n = tree_->findNamespaceNode(newPath);
+ n = qdb_->findNamespaceNode(newPath);
}
if (!n) {
}
else if (command == COMMAND_QMLINSTANTIATES) {
if ((node->type() == Node::Document) && (node->subType() == Node::QmlClass)) {
- ClassNode* classNode = tree_->findClassNode(arg.split("::"));
+ ClassNode* classNode = qdb_->findClassNode(arg.split("::"));
if (classNode)
node->setClassNode(classNode);
else
}
}
else {
- processCommonMetaCommand(doc.location(),command,argLocPair,node,tree_);
+ processCommonMetaCommand(doc.location(),command,argLocPair,node);
}
}
/*!
Resets the C++ code parser to its default initialized state.
*/
-void CppCodeParser::reset(Tree *tree)
+void CppCodeParser::reset()
{
- tree_ = tree;
tokenizer = 0;
tok = 0;
access = Node::Public;
metaness = FunctionNode::Plain;
- lastPath.clear();
+ lastPath_.clear();
moduleName.clear();
}
if (!matchDataType(&baseClass))
return false;
- tree_->addBaseClass(classe,
- access,
- baseClass.toPath(),
- baseClass.toString(),
- classe->parent());
+ qdb_->addBaseClass(classe,
+ access,
+ baseClass.toPath(),
+ baseClass.toString(),
+ classe->parent());
return true;
}
}
if (key == "READ")
- tree_->addPropertyFunction(property, value, PropertyNode::Getter);
+ qdb_->addPropertyFunction(property, value, PropertyNode::Getter);
else if (key == "WRITE") {
- tree_->addPropertyFunction(property, value, PropertyNode::Setter);
+ qdb_->addPropertyFunction(property, value, PropertyNode::Setter);
property->setWritable(true);
}
else if (key == "STORED")
}
}
else if (key == "RESET")
- tree_->addPropertyFunction(property, value, PropertyNode::Resetter);
+ qdb_->addPropertyFunction(property, value, PropertyNode::Resetter);
else if (key == "NOTIFY") {
- tree_->addPropertyFunction(property, value, PropertyNode::Notifier);
+ qdb_->addPropertyFunction(property, value, PropertyNode::Notifier);
} else if (key == "REVISION") {
int revision;
bool ok;
if (matchFunctionDecl(0, &parentPath, &clone)) {
foreach (const QString& usedNamespace_, activeNamespaces_) {
QStringList newPath = usedNamespace_.split("::") + parentPath;
- func = tree_->findFunctionNode(newPath, clone);
+ func = qdb_->findFunctionNode(newPath, clone);
if (func) {
break;
}
}
if (func == 0)
- func = tree_->findFunctionNode(parentPath, clone);
+ func = qdb_->findFunctionNode(parentPath, clone);
if (func) {
func->borrowParameterNames(clone);
delete clone;
}
else {
- doc.location().warning(
- tr("Cannot tie this documentation to anything"),
+ doc.location().warning(tr("Cannot tie this documentation to anything"),
tr("I found a /*! ... */ comment, but there was no "
"topic command (e.g., '\\%1', '\\%2') in the "
"comment and no function definition following "
if ((*n)->isInnerNode() &&
((InnerNode *)*n)->includes().isEmpty()) {
InnerNode *m = static_cast<InnerNode *>(*n);
- while (m->parent() != tree_->root())
+ while (m->parent() != qdb_->treeRoot())
m = m->parent();
if (m == *n)
((InnerNode *)*n)->addInclude((*n)->name());
Signals are implemented in uninteresting files
generated by moc.
*/
- node = tree_->findFunctionNode(parentPath, clone);
+ node = qdb_->findFunctionNode(parentPath, clone);
if (node != 0 && node->metaness() != FunctionNode::Signal)
node->setLocation(clone->location());
delete clone;
void CppCodeParser::instantiateIteratorMacro(const QString &container,
const QString &includeFile,
- const QString ¯oDef,
- Tree * /* tree */)
+ const QString ¯oDef)
{
QString resultingCode = macroDef;
resultingCode.replace(QRegExp("\\bC\\b"), container);
Tokenizer stringTokenizer(loc, latin1);
tokenizer = &stringTokenizer;
readToken();
- matchDeclList(tree_->root());
+ matchDeclList(QDocDatabase::qdocDB()->treeRoot());
}
void CppCodeParser::createExampleFileNodes(DocNode *dn)
**
****************************************************************************/
-/*
- cppcodeparser.h
-*/
-
#ifndef CPPCODEPARSER_H
#define CPPCODEPARSER_H
virtual QString language();
virtual QStringList headerFileNameFilter();
virtual QStringList sourceFileNameFilter();
- virtual void parseHeaderFile(const Location& location,
- const QString& filePath,
- Tree *tree);
- virtual void parseSourceFile(const Location& location,
- const QString& filePath,
- Tree *tree);
- virtual void doneParsingHeaderFiles(Tree *tree);
- virtual void doneParsingSourceFiles(Tree *tree);
-
- const FunctionNode *findFunctionNode(const QString& synopsis,
- Tree *tree,
- Node *relative = 0,
- bool fuzzy = false);
+ virtual void parseHeaderFile(const Location& location, const QString& filePath);
+ virtual void parseSourceFile(const Location& location, const QString& filePath);
+ virtual void doneParsingHeaderFiles();
+ virtual void doneParsingSourceFiles();
protected:
virtual QSet<QString> topicCommands();
void processOtherMetaCommands(const Doc& doc, Node *node);
protected:
- void reset(Tree *tree);
+ void reset();
void readToken();
const Location& location();
QString previousLexeme();
void parseQiteratorDotH(const Location &location, const QString &filePath);
void instantiateIteratorMacro(const QString &container,
const QString &includeFile,
- const QString ¯oDef,
- Tree *tree);
+ const QString ¯oDef);
void createExampleFileNodes(DocNode *dn);
protected:
QMap<QString, Node::Type> nodeTypeMap;
- Tree* tree_;
Tokenizer *tokenizer;
int tok;
Node::Access access;
FunctionNode::Metaness metaness;
QString moduleName;
- QStringList lastPath;
+ QStringList lastPath_;
QRegExp varComment;
QRegExp sep;
QSet<QString> activeNamespaces_;
#include "separator.h"
#include "tree.h"
#include <ctype.h>
+#include "qdocdatabase.h"
QT_BEGIN_NAMESPACE
}
/*!
- The default constructor.
+ Constructs the DITA XML output generator.
*/
DitaXmlGenerator::DitaXmlGenerator()
- : inContents(false),
- inDetailedDescription(false),
+ : inDetailedDescription(false),
inLegaleseText(false),
- inLink(false),
inObsoleteLink(false),
- inSectionHeading(false),
- inTableHeader(false),
inTableBody(false),
noLinks(false),
obsoleteLinks(false),
offlineDocs(true),
- threeColumnEnumValueTable(true),
codeIndent(0),
- numTableRows(0),
divNestingLevel(0),
sectionNestingLevel(0),
tableColumnCount(0),
nodeSubtypeMaps(Node::LastSubtype,0),
pageTypeMaps(Node::OnBeyondZebra,0)
{
- // nothing yet.
}
/*!
- The destructor has nothing to do.
+ Destroys the DITA XML output generator.
*/
DitaXmlGenerator::~DitaXmlGenerator()
{
}
/*!
- A lot of internal structures are initialized.
+ Initializes the DITA XML output generator's data structures
+ from the configuration class \a config.
*/
void DitaXmlGenerator::initializeGenerator(const Config &config)
{
}
/*!
- All this does is call the same function in the base class.
+ Gracefully terminates the DITA XML output generator.
*/
void DitaXmlGenerator::terminateGenerator()
{
}
/*!
- This is where the DITA XML files are written.
- \note The file is created in PageGenerator::generateTree().
+ Traverses the database generating all the DITA XML documentation.
*/
-void DitaXmlGenerator::generateTree(Tree *tree)
+void DitaXmlGenerator::generateTree()
{
- tree_ = tree;
- nonCompatClasses.clear();
- mainClasses.clear();
- compatClasses.clear();
- obsoleteClasses.clear();
- moduleClassMap.clear();
- moduleNamespaceMap.clear();
- funcIndex.clear();
- legaleseTexts.clear();
- serviceClasses.clear();
- qmlClasses.clear();
- findAllClasses(tree->root());
- findAllFunctions(tree->root());
- findAllLegaleseTexts(tree->root());
- findAllNamespaces(tree->root());
- findAllSince(tree->root());
-
- Generator::generateTree(tree);
+ qdb_->buildCollections();
+ Generator::generateTree();
generateCollisionPages();
QString fileBase = project.toLower().simplified().replace(QLatin1Char(' '), QLatin1Char('-'));
generateIndex(fileBase, projectUrl, projectDescription);
-
- writeDitaMap(tree);
-}
-
-void DitaXmlGenerator::startText(const Node* /* relative */,
- CodeMarker* /* marker */)
-{
- inLink = false;
- inContents = false;
- inSectionHeading = false;
- inTableHeader = false;
- numTableRows = 0;
- threeColumnEnumValueTable = true;
- link.clear();
- sectionNumber.clear();
+ writeDitaMap();
}
static int countTableColumns(const Atom* t)
case Atom::AbstractRight:
break;
case Atom::AutoLink:
- if (!noLinks && !inLink && !inContents && !inSectionHeading) {
+ if (!noLinks && !inLink_ && !inContents_ && !inSectionHeading_) {
const Node* node = 0;
- QString link = getLink(atom, relative, marker, &node);
+ QString link = getLink(atom, relative, &node);
if (!link.isEmpty()) {
beginLink(link);
- generateLink(atom, relative, marker);
+ generateLink(atom, marker);
endLink();
}
else {
break;
case Atom::C:
writeStartTag(DT_tt);
- if (inLink) {
+ if (inLink_) {
writeCharacters(protectEnc(plainCode(atom->string())));
}
else {
- writeText(atom->string(), marker, relative);
+ writeText(atom->string(), relative);
}
writeEndTag(); // see writeStartElement() above
break;
writeStartTag(DT_codeblock);
xmlWriter().writeAttribute("outputclass","cpp");
writeCharacters("\n");
- writeText(trimmedTrailing(atom->string()), marker, relative);
+ writeText(trimmedTrailing(atom->string()), relative);
writeEndTag(); // </codeblock>
}
break;
writeStartTag(DT_codeblock);
xmlWriter().writeAttribute("outputclass","qml");
writeCharacters("\n");
- writeText(trimmedTrailing(atom->string()), marker, relative);
+ writeText(trimmedTrailing(atom->string()), relative);
writeEndTag(); // </codeblock>
break;
case Atom::CodeNew:
writeEndTag(); // </p>
writeStartTag(DT_codeblock);
writeCharacters("\n");
- writeText(trimmedTrailing(atom->string()), marker, relative);
+ writeText(trimmedTrailing(atom->string()), relative);
writeEndTag(); // </codeblock>
break;
case Atom::CodeOld:
break;
case Atom::AnnotatedList:
{
- QList<Node*> values = tree_->groups().values(atom->string());
NodeMap nodeMap;
- for (int i = 0; i < values.size(); ++i) {
- const Node* n = values.at(i);
- if ((n->status() != Node::Internal) && (n->access() != Node::Private)) {
- nodeMap.insert(n->nameForLists(),n);
- }
- }
+ qdb_->getGroup(atom->string(), nodeMap);
generateAnnotatedList(relative, marker, nodeMap);
}
break;
case Atom::GeneratedList:
if (atom->string() == "annotatedclasses") {
- generateAnnotatedList(relative, marker, nonCompatClasses);
+ generateAnnotatedList(relative, marker, qdb_->getCppClasses());
}
else if (atom->string() == "classes") {
- generateCompactList(relative, marker, nonCompatClasses, true);
+ generateCompactList(relative, qdb_->getCppClasses(), true);
}
else if (atom->string() == "qmlclasses") {
- generateCompactList(relative, marker, qmlClasses, true);
+ generateCompactList(relative, qdb_->getQmlTypes(), true);
}
else if (atom->string().contains("classesbymodule")) {
QString arg = atom->string().trimmed();
- QString moduleName = atom->string().mid(atom->string().indexOf(
- "classesbymodule") + 15).trimmed();
- if (moduleClassMap.contains(moduleName))
- generateAnnotatedList(relative, marker, moduleClassMap[moduleName]);
+ QString moduleName = atom->string().mid(atom->string().indexOf("classesbymodule") + 15).trimmed();
+ QDocDatabase* qdb = QDocDatabase::qdocDB();
+ DocNode* dn = qdb->findModule(moduleName);
+ if (dn) {
+ NodeMap m;
+ dn->getMemberClasses(m);
+ if (!m.isEmpty()) {
+ generateAnnotatedList(relative, marker, m);
+ }
+ }
}
else if (atom->string().contains("classesbyedition")) {
QString arg = atom->string().trimmed();
- QString editionName = atom->string().mid(atom->string().indexOf(
- "classesbyedition") + 16).trimmed();
-
+ QString editionName = atom->string().mid(atom->string().indexOf("classesbyedition") + 16).trimmed();
if (editionModuleMap.contains(editionName)) {
-
+ QDocDatabase* qdb = QDocDatabase::qdocDB();
// Add all classes in the modules listed for that edition.
NodeMap editionClasses;
- foreach (const QString &moduleName, editionModuleMap[editionName]) {
- if (moduleClassMap.contains(moduleName))
- editionClasses.unite(moduleClassMap[moduleName]);
+ DocNodeMap::const_iterator i = qdb->modules().begin();
+ while (i != qdb->modules().end()) {
+ NodeMap m;
+ DocNode* dn = i.value();
+ dn->getMemberClasses(m);
+ if (!m.isEmpty())
+ editionClasses.unite(m);
+ m.clear();
+ ++i;
}
// Add additional groups and remove groups of classes that
// should be excluded from the edition.
- QMultiMap <QString, Node *> groups = tree_->groups();
+ const NodeMultiMap& groups = qdb_->groups();
foreach (const QString &groupName, editionGroupMap[editionName]) {
QList<Node *> groupClasses;
if (groupName.startsWith(QLatin1Char('-'))) {
}
}
else if (atom->string() == "classhierarchy") {
- generateClassHierarchy(relative, marker, nonCompatClasses);
+ generateClassHierarchy(relative, qdb_->getCppClasses());
}
else if (atom->string() == "compatclasses") {
- generateCompactList(relative, marker, compatClasses, false);
+ generateCompactList(relative, qdb_->getCompatibilityClasses(), false);
}
else if (atom->string() == "obsoleteclasses") {
- generateCompactList(relative, marker, obsoleteClasses, false);
+ generateCompactList(relative, qdb_->getObsoleteClasses(), false);
}
else if (atom->string() == "functionindex") {
- generateFunctionIndex(relative, marker);
+ generateFunctionIndex(relative);
}
else if (atom->string() == "legalese") {
generateLegaleseList(relative, marker);
}
else if (atom->string() == "mainclasses") {
- generateCompactList(relative, marker, mainClasses, true);
+ generateCompactList(relative, qdb_->getMainClasses(), true);
}
else if (atom->string() == "services") {
- generateCompactList(relative, marker, serviceClasses, false);
+ generateCompactList(relative, qdb_->getServiceClasses(), false);
}
else if (atom->string() == "overviews") {
- generateOverviewList(relative, marker);
+ generateOverviewList(relative);
}
else if (atom->string() == "namespaces") {
- generateAnnotatedList(relative, marker, namespaceIndex);
+ generateAnnotatedList(relative, marker, qdb_->getNamespaces());
}
else if (atom->string() == "related") {
const DocNode *dn = static_cast<const DocNode *>(relative);
- if (dn && !dn->groupMembers().isEmpty()) {
+ if (dn && !dn->members().isEmpty()) {
NodeMap groupMembersMap;
- foreach (const Node *node, dn->groupMembers()) {
+ foreach (const Node *node, dn->members()) {
if (node->type() == Node::Document)
- groupMembersMap[fullName(node, relative, marker)] = node;
+ groupMembersMap[node->fullName(relative)] = node;
}
generateAnnotatedList(dn, marker, groupMembersMap);
}
break;
case Atom::SinceList:
{
- NewSinceMaps::const_iterator nsmap;
- nsmap = newSinceMaps.constFind(atom->string());
- NewClassMaps::const_iterator ncmap;
- ncmap = newClassMaps.constFind(atom->string());
- NewClassMaps::const_iterator nqcmap;
- nqcmap = newQmlClassMaps.constFind(atom->string());
- if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) {
+ const NodeMultiMap& nsmap = qdb_->getSinceMap(atom->string());
+ const NodeMap& ncmap = qdb_->getClassMap(atom->string());
+ const NodeMap& nqcmap = qdb_->getQmlTypeMap(atom->string());
+ if (!nsmap.isEmpty()) {
QList<Section> sections;
QList<Section>::ConstIterator s;
+
for (int i=0; i<LastSinceType; ++i)
sections.append(Section(sinceTitle(i),QString(),QString(),QString()));
- NodeMultiMap::const_iterator n = nsmap.value().constBegin();
- while (n != nsmap.value().constEnd()) {
+ NodeMultiMap::const_iterator n = nsmap.constBegin();
+ while (n != nsmap.constEnd()) {
const Node* node = n.value();
switch (node->type()) {
case Node::Document:
++n;
}
- /*
- First generate the table of contents.
- */
writeStartTag(DT_ul);
s = sections.constBegin();
while (s != sections.constEnd()) {
writeCharacters(protectEnc((*s).name));
writeEndTag(); // </p>
if (idx == Class)
- generateCompactList(0, marker, ncmap.value(), false, QString("Q"));
+ generateCompactList(0, ncmap, false, QString("Q"));
else if (idx == QmlClass)
- generateCompactList(0, marker, nqcmap.value(), false, QString("Q"));
+ generateCompactList(0, nqcmap, false, QString("Q"));
else if (idx == MemberFunction) {
ParentMaps parentmaps;
ParentMaps::iterator pmap;
writeStartTag(DT_xref);
// formathtml
xmlWriter().writeAttribute("href",linkForNode(pmap.key(), 0));
- QStringList pieces = fullName(pmap.key(), 0, marker).split("::");
+ QStringList pieces = pmap.key()->fullName().split("::");
writeCharacters(protectEnc(pieces.last()));
writeEndTag(); // </xref>
xmlWriter().writeCharacters(":");
case Atom::Link:
{
const Node *node = 0;
- QString myLink = getLink(atom, relative, marker, &node);
+ QString myLink = getLink(atom, relative, &node);
if (myLink.isEmpty())
myLink = getCollisionLink(atom);
if (myLink.isEmpty())
relative->doc().location().warning(tr("Can't link to '%1'").arg(atom->string()));
- else if (!inSectionHeading)
+ else if (!inSectionHeading_)
beginLink(myLink);
skipAhead = 1;
}
writeStartTag(DT_dl);
}
else if (atom->string() == ATOM_LIST_VALUE) {
- threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
- if (threeColumnEnumValueTable) {
+ threeColumnEnumValueTable_ = isThreeColumnEnumValueTable(atom);
+ if (threeColumnEnumValueTable_) {
writeStartTag(DT_simpletable);
xmlWriter().writeAttribute("outputclass","valuelist");
writeStartTag(DT_sthead);
writeStartTag(DT_dd);
}
else if (atom->string() == ATOM_LIST_VALUE) {
- if (threeColumnEnumValueTable) {
+ if (threeColumnEnumValueTable_) {
writeEndTag(); // </stentry>
writeStartTag(DT_stentry);
}
writeGuidAttribute(id);
hx = QLatin1Char('h') + QString::number(atom->string().toInt() + hOffset(relative));
xmlWriter().writeAttribute("outputclass",hx);
- inSectionHeading = true;
+ inSectionHeading_ = true;
}
break;
case Atom::SectionHeadingRight:
writeEndTag(); // </title> (see case Atom::SectionHeadingLeft)
- inSectionHeading = false;
+ inSectionHeading_ = false;
break;
case Atom::SidebarLeft:
// nothing
// nothing
break;
case Atom::String:
- if (inLink && !inContents && !inSectionHeading) {
- generateLink(atom, relative, marker);
+ if (inLink_ && !inContents_ && !inSectionHeading_) {
+ generateLink(atom, marker);
}
else {
writeCharacters(atom->string());
writeStartTag(DT_table);
if (!attr.isEmpty())
xmlWriter().writeAttribute("outputclass",attr);
- numTableRows = 0;
+ numTableRows_ = 0;
if (tableColumnCount != 0) {
qDebug() << "ERROR: Nested tables!";
tableColumnCount = 0;
xmlWriter().writeAttribute("colwidth", QStringLiteral("1*"));
writeEndTag(); // DT_colspec
}
- inTableHeader = false;
+ inTableHeader_ = false;
inTableBody = false;
}
break;
writeEndTag(); // </tbody>
writeEndTag(); // </tgroup>
writeEndTag(); // </table>
- inTableHeader = false;
+ inTableHeader_ = false;
inTableBody = false;
tableColumnCount = 0;
currentColumn = 0;
writeEndTag(); // </tbody>
writeEndTag(); // </tgroup>
writeEndTag(); // </table>
- inTableHeader = false;
+ inTableHeader_ = false;
inTableBody = false;
tableColumnCount = 0;
writeStartTag(DT_table);
- numTableRows = 0;
+ numTableRows_ = 0;
tableColumnCount = countTableColumns(atom);
writeStartTag(DT_tgroup);
xmlWriter().writeAttribute("cols",QString::number(tableColumnCount));
xmlWriter().writeAttribute("valign","top");
writeStartTag(DT_row);
xmlWriter().writeAttribute("valign","top");
- inTableHeader = true;
+ inTableHeader_ = true;
inTableBody = false;
break;
case Atom::TableHeaderRight:
}
else {
writeEndTag(); // </thead>
- inTableHeader = false;
+ inTableHeader_ = false;
inTableBody = true;
writeStartTag(DT_tbody);
}
break;
case Atom::TableRowLeft:
- if (!inTableHeader && !inTableBody) {
+ if (!inTableHeader_ && !inTableBody) {
inTableBody = true;
writeStartTag(DT_tbody);
}
}
break;
case Atom::TableItemRight:
- if (inTableHeader) {
+ if (inTableHeader_) {
writeEndTag(); // </entry>
}
else {
columnText = pieces.at(0);
pieces.pop_front();
QString path = pieces.join(" ").trimmed();
- node = findNodeForTarget(path, relative, marker, atom);
- }
+ node = qdb_->findNodeForTarget(path, relative, atom);
+ if (!node)
+ relative->doc().location().warning(tr("Cannot link to '%1'").arg(path));
+ }
if (params.size() == 2) {
numColumns = qMax(columnText.toInt(), numColumns);
QString fullTitle;
if (inner->type() == Node::Namespace) {
const NamespaceNode* nsn = const_cast<NamespaceNode*>(static_cast<const NamespaceNode*>(inner));
- rawTitle = marker->plainName(inner);
- fullTitle = marker->plainFullName(inner);
+ rawTitle = inner->plainName();
+ fullTitle = inner->plainFullName();
title = rawTitle + " Namespace";
/*
writeCharacters(protectEnc((*s).name));
writeEndTag(); // </title>
generateSection(s->members, inner, marker, CodeMarker::Summary);
- generateSectionInheritedList(*s, inner, marker);
+ generateSectionInheritedList(*s, inner);
}
if (!s->reimpMembers.isEmpty()) {
QString name = QString("Reimplemented ") + (*s).name;
writeCharacters(protectEnc(name));
writeEndTag(); // </title>
generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
- generateSectionInheritedList(*s, inner, marker);
+ generateSectionInheritedList(*s, inner);
}
}
++s;
s = summarySections.constBegin();
while (s != summarySections.constEnd()) {
if (s->members.isEmpty())
- generateSectionInheritedList(*s, inner, marker);
+ generateSectionInheritedList(*s, inner);
++s;
}
}
}
else if (inner->type() == Node::Class) {
const ClassNode* cn = const_cast<ClassNode*>(static_cast<const ClassNode*>(inner));
- rawTitle = marker->plainName(inner);
- fullTitle = marker->plainFullName(inner);
+ rawTitle = inner->plainName();
+ fullTitle = inner->plainFullName();
title = rawTitle + " Class";
generateHeader(inner, fullTitle);
xmlWriter().writeAttribute("value","abstract");
writeEndTag(); // </cxxClassAbstract>
}
- writeDerivations(cn, marker); // <cxxClassDerivations>
+ writeDerivations(cn); // <cxxClassDerivations>
// not included: <cxxClassTemplateParameters>
writeCharacters(protectEnc((*s).name));
writeEndTag(); // </p>
generateSection(s->members, inner, marker, CodeMarker::Summary);
- generateSectionInheritedList(*s, inner, marker);
+ generateSectionInheritedList(*s, inner);
}
if (!s->reimpMembers.isEmpty()) {
QString name = QString("Reimplemented ") + (*s).name;
writeCharacters(protectEnc(name));
writeEndTag(); // </p>
generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
- generateSectionInheritedList(*s, inner, marker);
+ generateSectionInheritedList(*s, inner);
}
}
++s;
s = summarySections.constBegin();
while (s != summarySections.constEnd()) {
if (s->members.isEmpty())
- generateSectionInheritedList(*s, inner, marker);
+ generateSectionInheritedList(*s, inner);
++s;
}
}
}
else if ((inner->type() == Node::Document) && (inner->subType() == Node::HeaderFile)) {
const DocNode* dn = const_cast<DocNode*>(static_cast<const DocNode*>(inner));
- rawTitle = marker->plainName(inner);
- fullTitle = marker->plainFullName(inner);
+ rawTitle = inner->plainName();
+ fullTitle = inner->plainFullName();
title = rawTitle;
/*
writeCharacters(protectEnc((*s).name));
writeEndTag(); // </p>
generateSection(s->members, inner, marker, CodeMarker::Summary);
- generateSectionInheritedList(*s, inner, marker);
+ generateSectionInheritedList(*s, inner);
}
if (!s->reimpMembers.isEmpty()) {
QString name = QString("Reimplemented ") + (*s).name;
writeCharacters(protectEnc(name));
writeEndTag(); // </p>
generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
- generateSectionInheritedList(*s, inner, marker);
+ generateSectionInheritedList(*s, inner);
}
}
++s;
s = summarySections.constBegin();
while (s != summarySections.constEnd()) {
if (s->members.isEmpty())
- generateSectionInheritedList(*s, inner, marker);
+ generateSectionInheritedList(*s, inner);
++s;
}
}
else if ((inner->type() == Node::Document) && (inner->subType() == Node::QmlClass)) {
QmlClassNode* qcn = const_cast<QmlClassNode*>(static_cast<const QmlClassNode*>(inner));
ClassNode* cn = qcn->classNode();
- rawTitle = marker->plainName(inner);
- fullTitle = marker->plainFullName(inner);
+ rawTitle = inner->plainName();
+ fullTitle = inner->plainFullName();
title = rawTitle + " Type";
Node::clearPropertyGroupCount();
enterSection(QString(), QString());
if (dn->subType() == Node::Module) {
generateStatus(dn, marker);
- if (moduleNamespaceMap.contains(dn->name())) {
+ NodeMap nm;
+ dn->getMemberNamespaces(nm);
+ if (!nm.isEmpty()) {
enterSection("h2","Namespaces");
- generateAnnotatedList(dn, marker, moduleNamespaceMap[dn->name()]);
+ generateAnnotatedList(dn, marker, nm);
leaveSection();
}
- if (moduleClassMap.contains(dn->name())) {
+ nm.clear();
+ dn->getMemberClasses(nm);
+ if (!nm.isEmpty()) {
enterSection("h2","Classes");
- generateAnnotatedList(dn, marker, moduleClassMap[dn->name()]);
+ generateAnnotatedList(dn, marker, nm);
leaveSection();
}
+ nm.clear();
}
if (dn->doc().isEmpty()) {
}
generateAlsoList(dn, marker);
- if ((dn->subType() == Node::QmlModule) && !dn->qmlModuleMembers().isEmpty()) {
+ if ((dn->subType() == Node::QmlModule) && !dn->members().isEmpty()) {
NodeMap qmlModuleMembersMap;
- foreach (const Node* node, dn->qmlModuleMembers()) {
+ foreach (const Node* node, dn->members()) {
if (node->type() == Node::Document && node->subType() == Node::QmlClass)
qmlModuleMembersMap[node->name()] = node;
}
generateAnnotatedList(dn, marker, qmlModuleMembersMap);
}
- else if (!dn->groupMembers().isEmpty()) {
+ else if (!dn->members().isEmpty()) {
NodeMap groupMembersMap;
- foreach (const Node *node, dn->groupMembers()) {
+ foreach (const Node *node, dn->members()) {
if (node->type() == Node::Class || node->type() == Node::Namespace)
groupMembersMap[node->name()] = node;
}
dn->doc().location().warning(tr("Pop of empty XML tag stack; generating DITA for '%1'").arg(dn->name()));
return;
}
- writeRelatedLinks(dn, marker);
+ writeRelatedLinks(dn);
writeEndTag(); // </topic>
}
value of the \e role attribute is \c{parent} for the
\c{start} link.
*/
-void DitaXmlGenerator::writeRelatedLinks(const DocNode* node, CodeMarker* marker)
+void DitaXmlGenerator::writeRelatedLinks(const DocNode* node)
{
const Node* linkNode = 0;
QPair<QString,QString> linkPair;
writeStartTag(DT_relatedLinks);
if (node->links().contains(Node::PreviousLink)) {
linkPair = node->links()[Node::PreviousLink];
- linkNode = findNodeForTarget(linkPair.first, node, marker);
+ linkNode = qdb_->findNodeForTarget(linkPair.first, node);
+ if (!linkNode)
+ node->doc().location().warning(tr("Cannot link to '%1'").arg(linkPair.first));
if (linkNode && linkNode->type() == Node::Document) {
const DocNode *docNode = static_cast<const DocNode*>(linkNode);
linkPair.second = docNode->title();
}
if (node->links().contains(Node::NextLink)) {
linkPair = node->links()[Node::NextLink];
- linkNode = findNodeForTarget(linkPair.first, node, marker);
+ linkNode = qdb_->findNodeForTarget(linkPair.first, node);
+ if (!linkNode)
+ node->doc().location().warning(tr("Cannot link to '%1'").arg(linkPair.first));
if (linkNode && linkNode->type() == Node::Document) {
const DocNode *docNode = static_cast<const DocNode*>(linkNode);
linkPair.second = docNode->title();
}
if (node->links().contains(Node::StartLink)) {
linkPair = node->links()[Node::StartLink];
- linkNode = findNodeForTarget(linkPair.first, node, marker);
+ linkNode = qdb_->findNodeForTarget(linkPair.first, node);
+ if (!linkNode)
+ node->doc().location().warning(tr("Cannot link to '%1'").arg(linkPair.first));
if (linkNode && linkNode->type() == Node::Document) {
const DocNode *docNode = static_cast<const DocNode*>(linkNode);
linkPair.second = docNode->title();
}
// disable nested links in table of contents
- inContents = true;
- inLink = true;
+ inContents_ = true;
+ inLink_ = true;
for (int i = 0; i < toc.size(); ++i) {
Atom *atom = toc.at(i);
if (numColumns > 1)
out() << "</td></tr></table>\n";
- inContents = false;
- inLink = false;
-}
-
-/*!
- zzz
- Revised for the new doc format.
- Generates a table of contents beginning at \a node.
- */
-void DitaXmlGenerator::generateTableOfContents(const Node* node,
- CodeMarker* marker,
- QList<Section>* sections)
-{
- QList<Atom*> toc;
- if (node->doc().hasTableOfContents())
- toc = node->doc().tableOfContents();
- if (toc.isEmpty() && !sections && (node->subType() != Node::Module))
- return;
-
- QStringList sectionNumber;
- int detailsBase = 0;
-
- // disable nested links in table of contents
- inContents = true;
- inLink = true;
-
- out() << "<div class=\"toc\">\n";
- out() << "<h3>Contents</h3>\n";
- sectionNumber.append("1");
- out() << "<ul>\n";
-
- if (node->subType() == Node::Module) {
- if (moduleNamespaceMap.contains(node->name())) {
- out() << "<li class=\"level"
- << sectionNumber.size()
- << "\"><xref href=\"#"
- << registerRef("namespaces")
- << "\">Namespaces</xref></li>\n";
- }
- if (moduleClassMap.contains(node->name())) {
- out() << "<li class=\"level"
- << sectionNumber.size()
- << "\"><xref href=\"#"
- << registerRef("classes")
- << "\">Classes</xref></li>\n";
- }
- out() << "<li class=\"level"
- << sectionNumber.size()
- << "\"><xref href=\"#"
- << registerRef("details")
- << "\">Detailed Description</xref></li>\n";
- for (int i = 0; i < toc.size(); ++i) {
- if (toc.at(i)->string().toInt() == 1) {
- detailsBase = 1;
- break;
- }
- }
- }
- else if (sections && (node->type() == Node::Class)) {
- QList<Section>::ConstIterator s = sections->constBegin();
- while (s != sections->constEnd()) {
- if (!s->members.isEmpty() || !s->reimpMembers.isEmpty()) {
- out() << "<li class=\"level"
- << sectionNumber.size()
- << "\"><xref href=\"#"
- << registerRef((*s).pluralMember)
- << "\">" << (*s).name
- << "</xref></li>\n";
- }
- ++s;
- }
- out() << "<li class=\"level"
- << sectionNumber.size()
- << "\"><xref href=\"#"
- << registerRef("details")
- << "\">Detailed Description</xref></li>\n";
- for (int i = 0; i < toc.size(); ++i) {
- if (toc.at(i)->string().toInt() == 1) {
- detailsBase = 1;
- break;
- }
- }
- }
-
- for (int i = 0; i < toc.size(); ++i) {
- Atom *atom = toc.at(i);
- int nextLevel = atom->string().toInt() + detailsBase;
- if (sectionNumber.size() < nextLevel) {
- do {
- sectionNumber.append("1");
- } while (sectionNumber.size() < nextLevel);
- }
- else {
- while (sectionNumber.size() > nextLevel) {
- sectionNumber.removeLast();
- }
- sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
- }
- int numAtoms;
- Text headingText = Text::sectionHeading(atom);
- QString s = headingText.toString();
- out() << "<li class=\"level"
- << sectionNumber.size()
- << "\">";
- out() << "<xref href=\""
- << '#'
- << Doc::canonicalTitle(s)
- << "\">";
- generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms);
- out() << "</xref></li>\n";
- }
- while (!sectionNumber.isEmpty()) {
- sectionNumber.removeLast();
- }
- out() << "</ul>\n";
- out() << "</div>\n";
- inContents = false;
- inLink = false;
+ inContents_ = false;
+ inLink_ = false;
}
void DitaXmlGenerator::generateLowStatusMembers(const InnerNode* inner,
/*!
Write the XML for the class hierarchy to the current XML stream.
*/
-void DitaXmlGenerator::generateClassHierarchy(const Node* relative,
- CodeMarker* marker,
- const QMap<QString,const Node*>& classMap)
+void DitaXmlGenerator::generateClassHierarchy(const Node* relative, const NodeMap& classMap)
{
if (classMap.isEmpty())
return;
const ClassNode *child =
static_cast<const ClassNode *>(*stack.top().constBegin());
writeStartTag(DT_li);
- generateFullName(child, relative, marker);
+ generateFullName(child, relative);
writeEndTag(); // </li>
stack.top().erase(stack.top().begin());
writeStartTag(DT_row);
writeStartTag(DT_entry);
writeStartTag(DT_p);
- generateFullName(node, relative, marker);
+ generateFullName(node, relative);
writeEndTag(); // </p>
writeEndTag(); // <entry>
the name of the first and last classes in \a classMap.
*/
void DitaXmlGenerator::generateCompactList(const Node* relative,
- CodeMarker* marker,
const NodeMap& classMap,
bool includeAlphabet,
QString commonPrefix)
if (it.value()->subType() == Node::QmlClass)
pieces << it.value()->name();
else
- pieces = fullName(it.value(), relative, marker).split("::");
+ pieces = it.value()->fullName(relative).split("::");
xmlWriter().writeCharacters(protectEnc(pieces.last()));
writeEndTag(); // </xref>
if (pieces.size() > 1) {
xmlWriter().writeCharacters(" (");
- generateFullName(it.value()->parent(),relative,marker);
+ generateFullName(it.value()->parent(),relative);
xmlWriter().writeCharacters(")");
}
}
/*!
Write XML for a function index to the current XML stream.
*/
-void DitaXmlGenerator::generateFunctionIndex(const Node* relative,
- CodeMarker* marker)
+void DitaXmlGenerator::generateFunctionIndex(const Node* relative)
{
writeStartTag(DT_p);
xmlWriter().writeAttribute("outputclass","alphabet");
char currentLetter;
writeStartTag(DT_ul);
- QMap<QString, NodeMap >::ConstIterator f = funcIndex.constBegin();
+ NodeMapMap& funcIndex = qdb_->getFunctionIndex();
+ NodeMapMap::ConstIterator f = funcIndex.constBegin();
while (f != funcIndex.constEnd()) {
writeStartTag(DT_li);
currentLetter = f.key()[0].unicode();
NodeMap::ConstIterator s = (*f).constBegin();
while (s != (*f).constEnd()) {
- generateFullName((*s)->parent(), relative, marker, *s);
+ generateFullName((*s)->parent(), relative, *s);
++s;
}
writeEndTag(); // </li>
/*!
Write the legalese texts as XML to the current XML stream.
*/
-void DitaXmlGenerator::generateLegaleseList(const Node* relative,
- CodeMarker* marker)
+void DitaXmlGenerator::generateLegaleseList(const Node* relative, CodeMarker* marker)
{
- QMap<Text, const Node*>::ConstIterator it = legaleseTexts.constBegin();
+ TextToNodeMap& legaleseTexts = qdb_->getLegaleseTexts();
+ TextToNodeMap::ConstIterator it = legaleseTexts.constBegin();
while (it != legaleseTexts.constEnd()) {
Text text = it.key();
generateText(text, relative, marker);
writeStartTag(DT_ul);
do {
writeStartTag(DT_li);
- generateFullName(it.value(), relative, marker);
+ generateFullName(it.value(), relative);
writeEndTag(); // </li>
++it;
} while (it != legaleseTexts.constEnd() && it.key() == text);
marked.remove("<@type>");
marked.remove("</@type>");
}
- writeText(marked, marker, relative);
+ writeText(marked, relative);
}
/*!
Write the XML for the overview list to the current XML stream.
*/
-void DitaXmlGenerator::generateOverviewList(const Node* relative, CodeMarker* /* marker */)
+void DitaXmlGenerator::generateOverviewList(const Node* relative)
{
QMap<const DocNode*, QMap<QString, DocNode*> > docNodeMap;
QMap<QString, const DocNode*> groupTitlesMap;
QMap<QString, DocNode*> uncategorizedNodeMap;
QRegExp singleDigit("\\b([0-9])\\b");
- const NodeList children = tree_->root()->childNodes();
+ const NodeList children = qdb_->treeRoot()->childNodes();
foreach (Node* child, children) {
if (child->type() == Node::Document && child != relative) {
DocNode* docNode = static_cast<DocNode*>(child);
if (isGroupPage) {
// If we encounter a group definition page, we add all
// the pages in that group to the list for that group.
- foreach (Node* member, docNode->groupMembers()) {
+ foreach (Node* member, docNode->members()) {
if (member->type() != Node::Document)
continue;
DocNode* page = static_cast<DocNode*>(member);
else if (!isGroupPage) {
// If we encounter a page that belongs to a group then
// we add that page to the list for that group.
- const DocNode* gn = tree_->findGroupNode(QStringList(group));
+ const DocNode* gn = qdb_->findGroupNode(QStringList(group));
if (gn)
docNodeMap[gn].insert(sortKey, docNode);
}
if ((*m)->access() != Node::Private) {
writeStartTag(DT_li);
QString marked = getMarkedUpSynopsis(*m, relative, marker, style);
- writeText(marked, marker, relative);
+ writeText(marked, relative);
writeEndTag(); // </li>
}
++m;
/*!
Writes the "inherited from" list to the current XML stream.
*/
-void DitaXmlGenerator::generateSectionInheritedList(const Section& section,
- const Node* relative,
- CodeMarker* marker)
+void DitaXmlGenerator::generateSectionInheritedList(const Section& section, const Node* relative)
{
if (section.inherited.isEmpty())
return;
text = fileName((*p).first) + QLatin1Char('#');
text += DitaXmlGenerator::cleanRef(section.name.toLower());
xmlWriter().writeAttribute("href",text);
- text = protectEnc(marker->plainFullName((*p).first, relative));
+ text = protectEnc((*p).first->plainFullName(relative));
writeCharacters(text);
writeEndTag(); // </xref>
writeEndTag(); // </li>
from \a markedCode , and then the text is written to the current XML
stream.
*/
-void DitaXmlGenerator::writeText(const QString& markedCode,
- CodeMarker* marker,
- const Node* relative)
+void DitaXmlGenerator::writeText(const QString& markedCode, const Node* relative)
{
QString src = markedCode;
QString text;
}
par1 = QStringRef();
QString link;
- n = marker->resolveTarget(arg.toString(), tree_, relative);
+ n = qdb_->resolveTarget(arg.toString(), relative);
if (n && n->subType() == Node::QmlBasicType) {
if (relative && relative->subType() == Node::QmlClass) {
link = linkForNode(n,relative);
}
}
-void DitaXmlGenerator::generateLink(const Atom* atom,
- const Node* /* relative */,
- CodeMarker* marker)
+void DitaXmlGenerator::generateLink(const Atom* atom, CodeMarker* marker)
{
static QRegExp camelCase("[A-Z][A-Z][a-z]|[a-z][A-Z0-9]|_");
// hack for C++: move () outside of link
int k = funcLeftParen.pos(1);
writeCharacters(protectEnc(atom->string().left(k)));
- if (link.isEmpty()) {
+ if (link_.isEmpty()) {
if (showBrokenLinks)
writeEndTag(); // </i>
}
else
writeEndTag(); // </xref>
- inLink = false;
+ inLink_ = false;
writeCharacters(protectEnc(atom->string().mid(k)));
}
else if (marker->recognizeLanguage("Java")) {
void DitaXmlGenerator::generateFullName(const Node* apparentNode,
const Node* relative,
- CodeMarker* marker,
const Node* actualNode)
{
if (actualNode == 0)
// formathtml
QString href = linkForNode(actualNode, relative);
writeHrefAttribute(href);
- writeCharacters(protectEnc(fullName(apparentNode, relative, marker)));
+ writeCharacters(protectEnc(apparentNode->fullName(relative)));
writeEndTag(); // </xref>
}
-void DitaXmlGenerator::findAllClasses(const InnerNode* node)
-{
- NodeList::const_iterator c = node->childNodes().constBegin();
- while (c != node->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private && (*c)->url().isEmpty()) {
- if ((*c)->type() == Node::Class && !(*c)->doc().isEmpty()) {
- QString className = (*c)->name();
- if ((*c)->parent() &&
- (*c)->parent()->type() == Node::Namespace &&
- !(*c)->parent()->name().isEmpty())
- className = (*c)->parent()->name()+"::"+className;
-
- if (!(static_cast<const ClassNode *>(*c))->hideFromMainList()) {
- if ((*c)->status() == Node::Compat) {
- compatClasses.insert(className, *c);
- }
- else if ((*c)->status() == Node::Obsolete) {
- obsoleteClasses.insert(className, *c);
- }
- else {
- nonCompatClasses.insert(className, *c);
- if ((*c)->status() == Node::Main)
- mainClasses.insert(className, *c);
- }
- }
-
- QString moduleName = (*c)->moduleName();
- if (moduleName == "Qt3SupportLight") {
- moduleClassMap[moduleName].insert((*c)->name(), *c);
- moduleName = "Qt3Support";
- }
- if (!moduleName.isEmpty())
- moduleClassMap[moduleName].insert((*c)->name(), *c);
-
- QString serviceName =
- (static_cast<const ClassNode *>(*c))->serviceName();
- if (!serviceName.isEmpty())
- serviceClasses.insert(serviceName, *c);
- }
- else if ((*c)->type() == Node::Document &&
- (*c)->subType() == Node::QmlClass &&
- !(*c)->doc().isEmpty()) {
- QString qmlClassName = (*c)->name();
- qmlClasses.insert(qmlClassName,*c);
- }
- else if ((*c)->isInnerNode()) {
- findAllClasses(static_cast<InnerNode *>(*c));
- }
- }
- ++c;
- }
-}
-
-void DitaXmlGenerator::findAllFunctions(const InnerNode* node)
-{
- NodeList::ConstIterator c = node->childNodes().constBegin();
- while (c != node->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private) {
- if ((*c)->isInnerNode() && (*c)->url().isEmpty()) {
- findAllFunctions(static_cast<const InnerNode*>(*c));
- }
- else if ((*c)->type() == Node::Function) {
- const FunctionNode* func = static_cast<const FunctionNode*>(*c);
- if ((func->status() > Node::Obsolete) &&
- !func->isInternal() &&
- (func->metaness() != FunctionNode::Ctor) &&
- (func->metaness() != FunctionNode::Dtor)) {
- funcIndex[(*c)->name()].insert((*c)->parent()->fullDocumentName(), *c);
- }
- }
- }
- ++c;
- }
-}
-
-void DitaXmlGenerator::findAllLegaleseTexts(const InnerNode* node)
-{
- NodeList::ConstIterator c = node->childNodes().constBegin();
- while (c != node->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private) {
- if (!(*c)->doc().legaleseText().isEmpty())
- legaleseTexts.insertMulti((*c)->doc().legaleseText(), *c);
- if ((*c)->isInnerNode())
- findAllLegaleseTexts(static_cast<const InnerNode *>(*c));
- }
- ++c;
- }
-}
-
-void DitaXmlGenerator::findAllNamespaces(const InnerNode* node)
-{
- NodeList::ConstIterator c = node->childNodes().constBegin();
- while (c != node->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private) {
- if ((*c)->isInnerNode() && (*c)->url().isEmpty()) {
- findAllNamespaces(static_cast<const InnerNode *>(*c));
- if ((*c)->type() == Node::Namespace) {
- const NamespaceNode *nspace = static_cast<const NamespaceNode *>(*c);
- // Ensure that the namespace's name is not empty (the root
- // namespace has no name).
- if (!nspace->name().isEmpty()) {
- namespaceIndex.insert(nspace->name(), *c);
- QString moduleName = (*c)->moduleName();
- if (moduleName == "Qt3SupportLight") {
- moduleNamespaceMap[moduleName].insert((*c)->name(), *c);
- moduleName = "Qt3Support";
- }
- if (!moduleName.isEmpty())
- moduleNamespaceMap[moduleName].insert((*c)->name(), *c);
- }
- }
- }
- }
- ++c;
- }
-}
-
/*!
We're writing an attribute that indicates that the text
data is a heading, hence, h1, h2, h3... etc, and we must
return false;
}
-const Node* DitaXmlGenerator::findNodeForTarget(const QString& target,
- const Node* relative,
- CodeMarker* marker,
- const Atom* atom)
-{
- const Node* node = 0;
-
- if (target.isEmpty()) {
- node = relative;
- }
- else if (target.endsWith(".html")) {
- node = tree_->root()->findChildNodeByNameAndType(target, Node::Document);
- }
- else if (marker) {
- node = marker->resolveTarget(target, tree_, relative);
- if (!node)
- node = tree_->findDocNodeByTitle(target, relative);
- if (!node && atom) {
- node = tree_->findUnambiguousTarget(target, *const_cast<Atom**>(&atom), relative);
- }
- }
-
- if (!node)
- relative->doc().location().warning(tr("Cannot link to '%1'").arg(target));
-
- return node;
-}
-
const QPair<QString,QString> DitaXmlGenerator::anchorForNode(const Node* node)
{
QPair<QString,QString> anchorPair;
return anchorPair;
}
-QString DitaXmlGenerator::getLink(const Atom* atom,
- const Node* relative,
- CodeMarker* marker,
- const Node** node)
+QString DitaXmlGenerator::getLink(const Atom* atom, const Node* relative, const Node** node)
{
QString link;
*node = 0;
*node = relative;
}
else if (first.endsWith(".html")) {
- *node = tree_->root()->findChildNodeByNameAndType(first, Node::Document);
+ *node = qdb_->treeRoot()->findChildNodeByNameAndType(first, Node::Document);
}
else {
- *node = marker->resolveTarget(first, tree_, relative);
+ *node = qdb_->resolveTarget(first, relative);
if (!*node)
- *node = tree_->findDocNodeByTitle(first, relative);
+ *node = qdb_->findDocNodeByTitle(first, relative);
if (!*node)
- *node = tree_->findUnambiguousTarget(first, targetAtom, relative);
+ *node = qdb_->findUnambiguousTarget(first, targetAtom, relative);
}
if (*node) {
if (fake->title().startsWith("Porting"))
porting = true;
}
- QString name = marker->plainFullName(relative);
+ QString name = relative->plainFullName();
if (!porting && !name.startsWith("Q3")) {
if (obsoleteLinks) {
relative->doc().location().warning(tr("Link to obsolete item '%1' in %2")
}
while (!path.isEmpty()) {
- targetAtom = tree_->findTarget(path.first(), *node);
+ targetAtom = qdb_->findTarget(path.first(), *node);
if (targetAtom == 0)
break;
path.removeFirst();
QString guid = lookupGuid(link,refForAtom(targetAtom,*node));
link += QLatin1Char('#') + guid;
}
- else if (!link.isEmpty() && *node &&
- (link.endsWith(".xml") || link.endsWith(".dita"))) {
+ else if (!link.isEmpty() && *node && (link.endsWith(".xml") || link.endsWith(".dita"))) {
link += QLatin1Char('#') + (*node)->guid();
}
}
const QString& url,
const QString& title)
{
- tree_->generateIndex(outputDir() + QLatin1Char('/') + fileBase + ".index", url, title, this);
+ qdb_->generateIndex(outputDir() + QLatin1Char('/') + fileBase + ".index", url, title, this);
}
void DitaXmlGenerator::generateStatus(const Node* node, CodeMarker* marker)
<< "We strongly advise against "
<< "using it in new code. See ";
- const DocNode *docNode = tree_->findDocNodeByTitle("Porting To Qt 4");
+ const DocNode *docNode = qdb_->findDocNodeByTitle("Porting To Qt 4");
Atom *targetAtom = 0;
if (docNode && node->type() == Node::Class) {
QString oldName(node->name());
oldName.remove(QLatin1Char('3'));
- targetAtom = tree_->findTarget(oldName,docNode);
+ targetAtom = qdb_->findTarget(oldName,docNode);
}
if (targetAtom) {
void DitaXmlGenerator::beginLink(const QString& link)
{
- this->link = link;
- if (link.isEmpty())
+ link_ = link;
+ if (link_.isEmpty())
return;
writeStartTag(DT_xref);
// formathtml
- writeHrefAttribute(link);
- inLink = true;
+ writeHrefAttribute(link_);
+ inLink_ = true;
}
void DitaXmlGenerator::endLink()
{
- if (inLink) {
- if (link.isEmpty()) {
+ if (inLink_) {
+ if (link_.isEmpty()) {
if (showBrokenLinks)
writeEndTag(); // </i>
}
writeEndTag(); // </xref>
}
}
- inLink = false;
+ inLink_ = false;
inObsoleteLink = false;
}
writeStartTag(DT_qmlPropertyDetail);
writeStartTag(DT_qmlPropertyDef);
if (!qpn->isReadOnlySet())
- qpn->setReadOnly(!qpn->isWritable(tree_));
+ qpn->setReadOnly(!qpn->isWritable(qdb_));
if (qpn->isReadOnly()) {
writeStartTag(DT_qmlQualifier);
xmlWriter().writeAttribute("name","read-only");
writeStartTag((DitaTag)((int)tag+1));
writeStartTag(DT_apiData);
QString marked = getMarkedUpSynopsis(n, relative, marker, CodeMarker::Detailed);
- writeText(marked, marker, relative);
+ writeText(marked, relative);
writeEndTag(); // </apiData>
if (node->isAttached()) {
writeStartTag(DT_qmlAttached);
//xmlWriter().writeAttribute("outputclass","inherited-by");
writeStartTag(DT_apiData);
Text text;
- appendSortedQmlNames(text,qcn,subs,marker);
+ appendSortedQmlNames(text,qcn,subs);
text << Atom::ParaRight;
generateText(text, qcn, marker);
writeEndTag(); // </apiData>
</cxxClassDerivation>
\endcode
*/
-void DitaXmlGenerator::writeDerivations(const ClassNode* cn, CodeMarker* marker)
+void DitaXmlGenerator::writeDerivations(const ClassNode* cn)
{
QList<RelatedClass>::ConstIterator r;
writeStartTag(DT_cxxClassBaseClass);
QString attr = fileName((*r).node) + QLatin1Char('#') + (*r).node->guid();
xmlWriter().writeAttribute("href",attr);
- writeCharacters(marker->plainFullName((*r).node));
+ writeCharacters((*r).node->plainFullName());
writeEndTag(); // </cxxClassBaseClass>
// not included: <ClassBaseStruct> or <cxxClassBaseUnion>
else {
writeStartTag(DT_cxxFunctionDeclaredType);
QString src = marker->typified(fn->returnType());
- replaceTypesWithLinks(fn,parent,marker,src);
+ replaceTypesWithLinks(fn,parent,src);
writeEndTag(); // <cxxFunctionDeclaredType>
}
if (rfn && !rfn->isInternal()) {
writeStartTag(DT_cxxFunctionReimplemented);
xmlWriter().writeAttribute("href",ditaXmlHref(rfn));
- writeCharacters(marker->plainFullName(rfn));
+ writeCharacters(rfn->plainFullName());
writeEndTag(); // </cxxFunctionReimplemented>
}
}
This function replaces class and enum names with <apiRelation>
elements, i.e. links.
*/
-void DitaXmlGenerator::replaceTypesWithLinks(const Node* n,
- const InnerNode* parent,
- CodeMarker* marker,
- QString& src)
+void DitaXmlGenerator::replaceTypesWithLinks(const Node* n, const InnerNode* parent, QString& src)
{
QStringRef arg;
QStringRef par1;
}
i += 2;
if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) {
- const Node* tn = marker->resolveTarget(arg.toString(), tree_, parent, n);
+ const Node* tn = qdb_->resolveTarget(arg.toString(), parent, n);
if (tn) {
//Do not generate a link from a C++ function to a QML Basic Type (such as int)
if (n->type() == Node::Function && tn->subType() == Node::QmlBasicType)
writeStartTag(DT_cxxFunctionParameter);
writeStartTag(DT_cxxFunctionParameterDeclaredType);
QString src = marker->typified((*p).leftType());
- replaceTypesWithLinks(fn,parent,marker,src);
+ replaceTypesWithLinks(fn,parent,src);
//writeCharacters((*p).leftType());
if (!(*p).rightType().isEmpty())
writeCharacters((*p).rightType());
PropertyNode* opn = (PropertyNode*)pn->overriddenFrom();
writeStartTag(DT_cxxVariableReimplemented);
xmlWriter().writeAttribute("href",ditaXmlHref(opn));
- writeCharacters(marker->plainFullName(opn));
+ writeCharacters(opn->plainFullName());
writeEndTag(); // </cxxVariableReimplemented>
}
FunctionNode* rfn = (FunctionNode*)fn->reimplementedFrom();
writeStartTag(DT_cxxDefineReimplemented);
xmlWriter().writeAttribute("href",ditaXmlHref(rfn));
- writeCharacters(marker->plainFullName(rfn));
+ writeCharacters(rfn->plainFullName());
writeEndTag(); // </cxxDefineReimplemented>
}
Creates the DITA map for the qdoc run. The map is written
to the file \e{qt.ditamap" in the DITA XML output directory.
*/
-void DitaXmlGenerator::writeDitaMap(Tree *tree)
+void DitaXmlGenerator::writeDitaMap()
{
QString doctype;
Remove #if 0 to get a flat ditamap.
*/
#if 0
- beginSubPage(tree->root(),"qt.ditamap");
+ beginSubPage(qdb_->treeRoot(),"qt.ditamap");
doctype = "<!DOCTYPE map PUBLIC \"-//OASIS//DTD DITA Map//EN\" \"map.dtd\">";
xmlWriter().writeDTD(doctype);
writeStartTag(DT_map);
nodeSubtypeMaps[i] = new NodeMultiMap;
for (unsigned i=0; i<Node::OnBeyondZebra; ++i)
pageTypeMaps[i] = new NodeMultiMap;
- Node* rootPageNode = collectNodesByTypeAndSubtype(tree->root());
+ Node* rootPageNode = collectNodesByTypeAndSubtype(qdb_->treeRoot());
- beginSubPage(tree->root(),"qt.ditamap");
+ beginSubPage(qdb_->treeRoot(),"qt.ditamap");
doctype = "<!DOCTYPE map PUBLIC \"-//OASIS//DTD DITA Map//EN\" \"map.dtd\">";
xmlWriter().writeDTD(doctype);
writeStartTag(DT_topicref);
xmlWriter().writeAttribute("navtitle",t->navtitle());
if (t->href().isEmpty()) {
- const DocNode* dn = tree_->findDocNodeByTitle(t->navtitle());
+ const DocNode* dn = qdb_->findDocNodeByTitle(t->navtitle());
if (dn)
xmlWriter().writeAttribute("href",fileName(dn));
}
virtual void terminateGenerator();
virtual QString format();
virtual bool canHandleFormat(const QString& format);
- virtual void generateTree(Tree *tree);
+ virtual void generateTree();
void generateCollisionPages();
QString protectEnc(const QString& string);
static QString sinceTitle(int i) { return sinceTitles[i]; }
protected:
- virtual void startText(const Node* relative, CodeMarker* marker);
virtual int generateAtom(const Atom* atom,
const Node* relative,
CodeMarker* marker);
QString fullQualification(const Node* n);
void writeCharacters(const QString& text);
- void writeDerivations(const ClassNode* cn, CodeMarker* marker);
+ void writeDerivations(const ClassNode* cn);
void writeLocation(const Node* n);
void writeFunctions(const Section& s,
const InnerNode* parent,
CodeMarker* marker,
const QString& attribute = QString());
void writeNestedClasses(const Section& s, const Node* n);
- void replaceTypesWithLinks(const Node* n,
- const InnerNode* parent,
- CodeMarker* marker,
- QString& src);
+ void replaceTypesWithLinks(const Node* n, const InnerNode* parent, QString& src);
void writeParameters(const FunctionNode* fn, const InnerNode* parent, CodeMarker* marker);
void writeEnumerations(const Section& s,
CodeMarker* marker,
CodeMarker* marker,
const QString& attribute = QString());
void writePropertyParameter(const QString& tag, const NodeList& nlist);
- void writeRelatedLinks(const DocNode* dn, CodeMarker* marker);
+ void writeRelatedLinks(const DocNode* dn);
void writeLink(const Node* node, const QString& tex, const QString& role);
void writeProlog(const InnerNode* inner);
bool writeMetadataElement(const InnerNode* inner,
enum SubTitleSize { SmallSubTitle, LargeSubTitle };
const QPair<QString,QString> anchorForNode(const Node* node);
- const Node* findNodeForTarget(const QString& target,
- const Node* relative,
- CodeMarker* marker,
- const Atom* atom = 0);
void generateHeader(const Node* node,
const QString& name,
bool subpage = false);
Doc::Sections sectioningUnit,
int numColumns,
const Node* relative = 0);
- void generateTableOfContents(const Node* node,
- CodeMarker* marker,
- QList<Section>* sections = 0);
void generateLowStatusMembers(const InnerNode* inner,
CodeMarker* marker,
CodeMarker::Status status);
QString generateLowStatusMemberFile(const InnerNode* inner,
CodeMarker* marker,
CodeMarker::Status status);
- void generateClassHierarchy(const Node* relative,
- CodeMarker* marker,
- const NodeMap& classMap);
+ void generateClassHierarchy(const Node* relative, const NodeMap& classMap);
void generateAnnotatedList(const Node* relative,
CodeMarker* marker,
const NodeMap& nodeMap);
void generateCompactList(const Node* relative,
- CodeMarker* marker,
const NodeMap& classMap,
bool includeAlphabet,
QString commonPrefix = QString());
- void generateFunctionIndex(const Node* relative, CodeMarker* marker);
+ void generateFunctionIndex(const Node* relative);
void generateLegaleseList(const Node* relative, CodeMarker* marker);
- void generateOverviewList(const Node* relative, CodeMarker* marker);
+ void generateOverviewList(const Node* relative);
void generateQmlSummary(const Section& section,
const Node* relative,
const Node* relative,
CodeMarker* marker,
CodeMarker::SynopsisStyle style);
- void generateSectionInheritedList(const Section& section,
- const Node* relative,
- CodeMarker* marker);
- void writeText(const QString& markedCode,
- CodeMarker* marker,
- const Node* relative);
+ void generateSectionInheritedList(const Section& section, const Node* relative);
+ void writeText(const QString& markedCode, const Node* relative);
- void generateFullName(const Node* apparentNode,
- const Node* relative,
- CodeMarker* marker,
- const Node* actualNode = 0);
- void generateLink(const Atom* atom,
- const Node* relative,
- CodeMarker* marker);
+ void generateFullName(const Node* apparentNode, const Node* relative, const Node* actualNode = 0);
+ void generateLink(const Atom* atom, CodeMarker* marker);
void generateStatus(const Node* node, CodeMarker* marker);
QString registerRef(const QString& ref);
virtual QString fileBase(const Node *node) const;
QString fileName(const Node *node);
- void findAllClasses(const InnerNode *node);
- void findAllFunctions(const InnerNode *node);
- void findAllLegaleseTexts(const InnerNode *node);
- void findAllNamespaces(const InnerNode *node);
static int hOffset(const Node *node);
static bool isThreeColumnEnumValueTable(const Atom *atom);
- QString getLink(const Atom *atom,
- const Node *relative,
- CodeMarker *marker,
- const Node **node);
+ QString getLink(const Atom *atom, const Node *relative, const Node **node);
virtual void generateIndex(const QString& fileBase,
const QString& url,
const QString& title);
QXmlStreamWriter& xmlWriter();
void writeApiDesc(const Node* node, CodeMarker* marker, const QString& title);
void addLink(const QString& href, const QStringRef& text, DitaTag t = DT_xref);
- void writeDitaMap(Tree* tree);
+ void writeDitaMap();
void writeDitaMap(const DitaMapNode* node);
void writeStartTag(DitaTag t);
bool writeEndTag(DitaTag t=DT_NONE);
These flags indicate which elements the generator
is currently outputting.
*/
- bool inContents;
bool inDetailedDescription;
bool inLegaleseText;
- bool inLink;
bool inObsoleteLink;
- bool inSectionHeading;
- bool inTableHeader;
bool inTableBody;
bool noLinks;
bool obsoleteLinks;
bool offlineDocs;
- bool threeColumnEnumValueTable;
int codeIndent;
- int numTableRows;
int divNestingLevel;
int sectionNestingLevel;
int tableColumnCount;
int currentColumn;
- QString link;
- QStringList sectionNumber;
QRegExp funcLeftParen;
QString style;
QString postHeader;
QMap<QString, QString> refMap;
QMap<QString, QString> name2guidMap;
GuidMaps guidMaps;
- QMap<QString, NodeMap > moduleClassMap;
- QMap<QString, NodeMap > moduleNamespaceMap;
- NodeMap nonCompatClasses;
- NodeMap mainClasses;
- NodeMap compatClasses;
- NodeMap obsoleteClasses;
- NodeMap namespaceIndex;
- NodeMap serviceClasses;
- NodeMap qmlClasses;
- QMap<QString, NodeMap > funcIndex;
- QMap<Text, const Node*> legaleseTexts;
static int id;
static QString ditaTags[];
QStack<QXmlStreamWriter*> xmlWriterStack;
if (atom) {
QString briefStr;
QString whats;
- bool standardWording = true;
-
/*
This code is really ugly. The entire \brief business
should be rethought.
else {
if (!w.isEmpty() && w.first() == "The")
w.removeFirst();
- else {
- location().warning(
- tr("Nonstandard wording in '\\%1' text for '%2' (expected 'The')")
- .arg(COMMAND_BRIEF).arg(className));
- standardWording = false;
- }
if (!w.isEmpty() && (w.first() == className || w.first() == classNameOnly))
w.removeFirst();
- else {
- location().warning(
- tr("Nonstandard wording in '\\%1' text for '%2' (expected '%3')")
- .arg(COMMAND_BRIEF).arg(className).arg(className));
- standardWording = false;
- }
if (!w.isEmpty() && ((w.first() == "class") ||
(w.first() == "function") ||
(w.first() == "namespace") ||
(w.first() == "header")))
w.removeFirst();
- else {
- location().warning(
- tr("Nonstandard wording in '\\%1' text for '%2' ("
- "expected 'class', 'function', 'macro', 'widget', "
- "'namespace' or 'header')")
- .arg(COMMAND_BRIEF).arg(className));
- standardWording = false;
- }
if (!w.isEmpty() && (w.first() == "is" || w.first() == "provides"))
w.removeFirst();
if (whats.endsWith(QLatin1Char('.')))
whats.truncate(whats.length() - 1);
- if (whats.isEmpty()) {
- location().warning(
- tr("Nonstandard wording in '\\%1' text for '%2' (expected more text)")
- .arg(COMMAND_BRIEF).arg(className));
- standardWording = false;
- }
- else
+ if (!whats.isEmpty())
whats[0] = whats[0].toUpper();
// ### move this once \brief is abolished for properties
- if (standardWording)
- resultText << whats;
+ resultText << whats;
}
return resultText;
}
#include "doc.h"
#include "editdistance.h"
#include "generator.h"
-#include "node.h"
#include "openedlist.h"
#include "quoter.h"
#include "separator.h"
#include "tokenizer.h"
-#include "tree.h"
+#include "qdocdatabase.h"
QT_BEGIN_NAMESPACE
QStringList Generator::styleDirs;
QStringList Generator::styleFiles;
-
+/*!
+ Constructs the generator base class. Prepends the newly
+ constructed generator to the list of output generators.
+ Sets a pointer to the QDoc database singleton, which is
+ available to the generator subclasses.
+ */
Generator::Generator()
: amp("&"),
gt(">"),
lt("<"),
quot("""),
tag("</?@[^>]*>"),
- tree_(0)
-{
+ inLink_(false),
+ inContents_(false),
+ inSectionHeading_(false),
+ inTableHeader_(false),
+ threeColumnEnumValueTable_(true),
+ numTableRows_(0)
+{
+ qdb_ = QDocDatabase::qdocDB();
generators.prepend(this);
}
+/*!
+ Destroys the generator after removing it from the list of
+ output generators.
+ */
Generator::~Generator()
{
generators.removeAll(this);
void Generator::appendFullName(Text& text,
const Node *apparentNode,
const Node *relative,
- CodeMarker *marker,
const Node *actualNode)
{
if (actualNode == 0)
actualNode = apparentNode;
text << Atom(Atom::LinkNode, CodeMarker::stringForNode(actualNode))
<< Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << Atom(Atom::String, marker->plainFullName(apparentNode, relative))
+ << Atom(Atom::String, apparentNode->plainFullName(relative))
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
}
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
}
-void Generator::appendFullNames(Text& text,
- const NodeList& nodes,
- const Node* relative,
- CodeMarker* marker)
+void Generator::appendFullNames(Text& text, const NodeList& nodes, const Node* relative)
{
NodeList::ConstIterator n = nodes.constBegin();
int index = 0;
while (n != nodes.constEnd()) {
- appendFullName(text,*n,relative,marker);
+ appendFullName(text,*n,relative);
text << comma(index++,nodes.count());
++n;
}
}
-void Generator::appendSortedNames(Text& text,
- const ClassNode *classe,
- const QList<RelatedClass> &classes,
- CodeMarker *marker)
+void Generator::appendSortedNames(Text& text, const ClassNode *classe, const QList<RelatedClass> &classes)
{
QList<RelatedClass>::ConstIterator r;
QMap<QString,Text> classMap;
(*r).node->status() != Node::Internal
&& !(*r).node->doc().isEmpty()) {
Text className;
- appendFullName(className, (*r).node, classe, marker);
+ appendFullName(className, (*r).node, classe);
classMap[className.toString().toLower()] = className;
}
++r;
}
}
-void Generator::appendSortedQmlNames(Text& text,
- const Node* base,
- const NodeList& subs,
- CodeMarker *marker)
+void Generator::appendSortedQmlNames(Text& text, const Node* base, const NodeList& subs)
{
QMap<QString,Text> classMap;
int index = 0;
Text t;
if (!base->isQtQuickNode() || !subs[i]->isQtQuickNode() ||
(base->qmlModuleIdentifier() == subs[i]->qmlModuleIdentifier())) {
- appendFullName(t, subs[i], base, marker);
+ appendFullName(t, subs[i], base);
classMap[t.toString().toLower()] = t;
}
}
delete outStreamStack.pop();
}
-void Generator::endText(const Node * /* relative */,
- CodeMarker * /* marker */)
-{
-}
-
QString Generator::fileBase(const Node *node) const
{
if (node->relates())
return name;
}
-/*!
- For generating the "New Classes... in x.y" section on the
- What's New in Qt x.y" page.
- */
-void Generator::findAllSince(const InnerNode *node)
-{
- NodeList::const_iterator child = node->childNodes().constBegin();
-
- // Traverse the tree, starting at the node supplied.
-
- while (child != node->childNodes().constEnd()) {
-
- QString sinceString = (*child)->since();
-
- if (((*child)->access() != Node::Private) && !sinceString.isEmpty()) {
-
- // Insert a new entry into each map for each new since string found.
- NewSinceMaps::iterator nsmap = newSinceMaps.find(sinceString);
- if (nsmap == newSinceMaps.end())
- nsmap = newSinceMaps.insert(sinceString,NodeMultiMap());
-
- NewClassMaps::iterator ncmap = newClassMaps.find(sinceString);
- if (ncmap == newClassMaps.end())
- ncmap = newClassMaps.insert(sinceString,NodeMap());
-
- NewClassMaps::iterator nqcmap = newQmlClassMaps.find(sinceString);
- if (nqcmap == newQmlClassMaps.end())
- nqcmap = newQmlClassMaps.insert(sinceString,NodeMap());
-
- if ((*child)->type() == Node::Function) {
- // Insert functions into the general since map.
- FunctionNode *func = static_cast<FunctionNode *>(*child);
- if ((func->status() > Node::Obsolete) &&
- (func->metaness() != FunctionNode::Ctor) &&
- (func->metaness() != FunctionNode::Dtor)) {
- nsmap.value().insert(func->name(),(*child));
- }
- }
- else if ((*child)->url().isEmpty()) {
- if ((*child)->type() == Node::Class && !(*child)->doc().isEmpty()) {
- // Insert classes into the since and class maps.
- QString className = (*child)->name();
- if ((*child)->parent() &&
- (*child)->parent()->type() == Node::Namespace &&
- !(*child)->parent()->name().isEmpty())
- className = (*child)->parent()->name()+"::"+className;
-
- nsmap.value().insert(className,(*child));
- ncmap.value().insert(className,(*child));
- }
- else if ((*child)->subType() == Node::QmlClass) {
- // Insert QML elements into the since and element maps.
- QString className = (*child)->name();
- if ((*child)->parent() &&
- (*child)->parent()->type() == Node::Namespace &&
- !(*child)->parent()->name().isEmpty())
- className = (*child)->parent()->name()+"::"+className;
-
- nsmap.value().insert(className,(*child));
- nqcmap.value().insert(className,(*child));
- }
- else if ((*child)->type() == Node::QmlProperty) {
- // Insert QML properties into the since map.
- QString propertyName = (*child)->name();
- nsmap.value().insert(propertyName,(*child));
- }
- }
- else {
- // Insert external documents into the general since map.
- QString name = (*child)->name();
- if ((*child)->parent() &&
- (*child)->parent()->type() == Node::Namespace &&
- !(*child)->parent()->name().isEmpty())
- name = (*child)->parent()->name()+"::"+name;
-
- nsmap.value().insert(name,(*child));
- }
-
- // Find child nodes with since commands.
- if ((*child)->isInnerNode()) {
- findAllSince(static_cast<InnerNode *>(*child));
- }
- }
- ++child;
- }
-}
-
QMap<QString, QString>& Generator::formattingLeftMap()
{
return fmtLeftMaps[format()];
return fdl + parentName.toLower() + anchorRef;
}
-QString Generator::fullName(const Node *node,
- const Node *relative,
- CodeMarker *marker) const
-{
- if (node->type() == Node::Document) {
- const DocNode* fn = static_cast<const DocNode *>(node);
-
- // Only print modulename::type on collision pages.
- if (!fn->qmlModuleIdentifier().isEmpty() && relative != 0 && relative->isCollisionNode())
- return fn->qmlModuleIdentifier() + "::" + fn->title();
-
- return fn->title();
- }
- else if (node->type() == Node::Class &&
- !(static_cast<const ClassNode *>(node))->serviceName().isEmpty())
- return (static_cast<const ClassNode *>(node))->serviceName();
- else
- return marker->plainFullName(node, relative);
-}
-
void Generator::generateAlsoList(const Node *node, CodeMarker *marker)
{
QList<Text> alsoList = node->doc().alsoList();
}
if (node->doc().isEmpty()) {
if (!quiet && !node->isReimp()) { // ### might be unnecessary
- node->location().warning(tr("No documentation for '%1'")
- .arg(marker->plainFullName(node)));
+ node->location().warning(tr("No documentation for '%1'").arg(node->plainFullName()));
}
}
else {
if (!best.isEmpty() && !documentedItems.contains(best))
details = tr("Maybe you meant '%1'?").arg(best);
- node->doc().location().warning(
- tr("No such enum item '%1' in %2").arg(*a).arg(marker->plainFullName(node)),
- details);
+ node->doc().location().warning(tr("No such enum item '%1' in %2").arg(*a).arg(node->plainFullName()), details);
if (*a == "Void")
qDebug() << "VOID:" << node->name() << definedItems;
}
else if (!documentedItems.contains(*a)) {
- node->doc().location().warning(
- tr("Undocumented enum item '%1' in %2").arg(*a).arg(marker->plainFullName(node)));
+ node->doc().location().warning(tr("Undocumented enum item '%1' in %2").arg(*a).arg(node->plainFullName()));
}
++a;
}
details = tr("Maybe you meant '%1'?").arg(best);
node->doc().location().warning(
- tr("No such parameter '%1' in %2").arg(*a).arg(marker->plainFullName(node)),
+ tr("No such parameter '%1' in %2").arg(*a).arg(node->plainFullName()),
details);
}
else if (!(*a).isEmpty() && !documentedParams.contains(*a)) {
if (needWarning && !func->isReimp())
node->doc().location().warning(
tr("Undocumented parameter '%1' in %2")
- .arg(*a).arg(marker->plainFullName(node)));
+ .arg(*a).arg(node->plainFullName()));
}
++a;
}
<< "Inherited by: "
<< Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD);
- appendSortedNames(text, classe, classe->derivedClasses(), marker);
+ appendSortedNames(text, classe, classe->derivedClasses());
text << Atom::ParaRight;
generateText(text, classe, marker);
}
if (!subs.isEmpty()) {
Text text;
text << Atom::ParaLeft << "Inherited by ";
- appendSortedQmlNames(text,qcn,subs,marker);
+ appendSortedQmlNames(text,qcn,subs);
text << Atom::ParaRight;
generateText(text, qcn, marker);
}
bool result = false;
if (atom != 0) {
- startText(relative, marker);
+ initializeTextOutput();
while (atom) {
if (atom->type() != Atom::QmlText)
atom = atom->next();
}
}
}
- endText(relative, marker);
result = true;
}
return result;
bool result = false;
if (text.firstAtom() != 0) {
int numAtoms = 0;
- startText(relative, marker);
+ initializeTextOutput();
generateAtomList(text.firstAtom(),
relative,
marker,
true,
numAtoms);
- endText(relative, marker);
result = true;
}
return result;
if (nonreentrant.isEmpty()) {
if (!threadsafe.isEmpty()) {
text << ", but ";
- appendFullNames(text,threadsafe,innerNode,marker);
+ appendFullNames(text,threadsafe,innerNode);
singularPlural(text,threadsafe);
text << " also " << tlink << ".";
}
}
else {
text << ", except for ";
- appendFullNames(text,nonreentrant,innerNode,marker);
+ appendFullNames(text,nonreentrant,innerNode);
text << ", which";
singularPlural(text,nonreentrant);
text << " nonreentrant.";
if (!threadsafe.isEmpty()) {
text << " ";
- appendFullNames(text,threadsafe,innerNode,marker);
+ appendFullNames(text,threadsafe,innerNode);
singularPlural(text,threadsafe);
text << " " << tlink << ".";
}
if (!nonreentrant.isEmpty() || !reentrant.isEmpty()) {
text << ", except for ";
if (!reentrant.isEmpty()) {
- appendFullNames(text,reentrant,innerNode,marker);
+ appendFullNames(text,reentrant,innerNode);
text << ", which";
singularPlural(text,reentrant);
text << " only " << rlink;
text << ", and ";
}
if (!nonreentrant.isEmpty()) {
- appendFullNames(text,nonreentrant,innerNode,marker);
+ appendFullNames(text,nonreentrant,innerNode);
text << ", which";
singularPlural(text,nonreentrant);
text << " nonreentrant.";
}
/*!
- This function is recursive.
+ Traverses the database recursivly to generate all the documentation.
*/
-void Generator::generateTree(Tree *tree)
+void Generator::generateTree()
{
- tree_ = tree;
- generateInnerNode(tree->root());
+ generateInnerNode(qdb_->treeRoot());
}
Generator *Generator::generatorForFormat(const QString& format)
if (!atom->string().contains("::"))
return link;
QStringList path = atom->string().split("::");
- NameCollisionNode* ncn = tree_->findCollisionNode(path[0]);
+ NameCollisionNode* ncn = qdb_->findCollisionNode(path[0]);
if (ncn) {
QString label;
if (atom->next() && atom->next()->next()) {
return skipAhead;
}
-void Generator::startText(const Node * /* relative */,
- CodeMarker * /* marker */)
-{
+/*!
+ Resets the variables used during text output.
+ */
+void Generator::initializeTextOutput()
+{
+ inLink_ = false;
+ inContents_ = false;
+ inSectionHeading_ = false;
+ inTableHeader_ = false;
+ numTableRows_ = 0;
+ threeColumnEnumValueTable_ = true;
+ link_.clear();
+ sectionNumber_.clear();
}
void Generator::supplementAlsoList(const Node *node, QList<Text> &alsoList)
**
****************************************************************************/
-/*
- generator.h
-*/
-
#ifndef GENERATOR_H
#define GENERATOR_H
QT_BEGIN_NAMESPACE
-typedef QMap<QString, NodeMap> NewClassMaps;
-typedef QMap<QString, NodeMultiMap> NewSinceMaps;
typedef QMap<QString, const Node*> NodeMap;
typedef QMultiMap<QString, Node*> NodeMultiMap;
typedef QMap<Node*, NodeMultiMap> ParentMaps;
-class ClassNode;
class Config;
class CodeMarker;
-class DocNode;
-class FunctionNode;
-class InnerNode;
class Location;
-class NamespaceNode;
-class Node;
-class Tree;
+class QDocDatabase;
class Generator
{
virtual bool canHandleFormat(const QString &format) { return format == this->format(); }
virtual QString format() = 0;
- virtual void generateTree(Tree *tree);
+ virtual void generateTree();
virtual void initializeGenerator(const Config &config);
virtual void terminateGenerator();
protected:
virtual void beginSubPage(const InnerNode* node, const QString& fileName);
virtual void endSubPage();
- virtual void endText(const Node *relative, CodeMarker *marker);
virtual QString fileBase(const Node* node) const;
virtual QString fileExtension() const = 0;
- virtual QString fullName(const Node *node,
- const Node *relative,
- CodeMarker *marker) const;
virtual void generateAlsoList(const Node *node, CodeMarker *marker);
virtual int generateAtom(const Atom *atom,
const Node *relative,
const Node *relative,
CodeMarker *marker);
virtual QString imageFileName(const Node *relative, const QString& fileBase);
- virtual int skipAtoms(const Atom *atom, Atom::Type type) const;
- virtual void startText(const Node *relative, CodeMarker *marker);
+ virtual int skipAtoms(const Atom *atom, Atom::Type type) const;
virtual QString typeString(const Node *node);
static bool matchAhead(const Atom *atom, Atom::Type expectedAtomType);
static QString trimmedTrailing(const QString &string);
static QString sinceTitles[];
+ void initializeTextOutput();
QString fileName(const Node* node) const;
- void findAllSince(const InnerNode *node);
QMap<QString, QString> &formattingLeftMap();
QMap<QString, QString> &formattingRightMap();
const Atom* generateAtomList(const Atom *atom,
QString plainCode(const QString& markedCode);
void setImageFileExtensions(const QStringList& extensions);
void unknownAtom(const Atom *atom);
- void appendSortedQmlNames(Text& text,
- const Node* base,
- const NodeList& subs,
- CodeMarker *marker);
+ void appendSortedQmlNames(Text& text, const Node* base, const NodeList& subs);
QList<NameCollisionNode*> collisionNodes;
QMap<QString, QStringList> editionGroupMap;
QTextCodec* outputCodec;
QString outputEncoding;
QStack<QTextStream*> outStreamStack;
- NewClassMaps newClassMaps;
- NewClassMaps newQmlClassMaps;
- NewSinceMaps newSinceMaps;
private:
static QString baseDir_;
void appendFullName(Text& text,
const Node *apparentNode,
const Node *relative,
- CodeMarker *marker,
const Node *actualNode = 0);
void appendFullName(Text& text,
const Node *apparentNode,
const QString& fullName,
const Node *actualNode);
- void appendFullNames(Text& text,
- const NodeList& nodes,
- const Node* relative,
- CodeMarker* marker);
- void appendSortedNames(Text& text,
- const ClassNode *classe,
- const QList<RelatedClass> &classes,
- CodeMarker *marker);
- void generateReimplementedFrom(const FunctionNode *func,
- CodeMarker *marker);
+ void appendFullNames(Text& text, const NodeList& nodes, const Node* relative);
+ void appendSortedNames(Text& text, const ClassNode *classe, const QList<RelatedClass> &classes);
+ void generateReimplementedFrom(const FunctionNode *func, CodeMarker *marker);
QString amp;
QString gt;
QRegExp tag;
protected:
- Tree* tree_;
+ QDocDatabase* qdb_;
+ bool inLink_;
+ bool inContents_;
+ bool inSectionHeading_;
+ bool inTableHeader_;
+ bool threeColumnEnumValueTable_;
+ int numTableRows_;
+ QString link_;
+ QString sectionNumber_;
};
QT_END_NAMESPACE
#include "htmlgenerator.h"
#include "config.h"
#include "node.h"
-#include "tree.h"
+#include "qdocdatabase.h"
+#include <qdebug.h>
QT_BEGIN_NAMESPACE
Generator* g)
: gen_(g)
{
+ /*
+ Get the pointer to the singleton for the qdoc database and
+ store it locally. This replaces all the local accesses to
+ the node tree, which are now private.
+ */
+ qdb_ = QDocDatabase::qdocDB();
+
// The output directory should already have been checked by the calling
// generator.
outputDir = config.getOutputDir();
}
}
-void HelpProjectWriter::generate(const Tree *t)
+void HelpProjectWriter::generate()
{
- this->tree = t;
for (int i = 0; i < projects.size(); ++i)
generateProject(projects[i]);
}
{
const Node *rootNode;
if (!project.indexRoot.isEmpty())
- rootNode = tree->findDocNodeByTitle(project.indexRoot);
+ rootNode = qdb_->findDocNodeByTitle(project.indexRoot);
else
- rootNode = tree->root();
+ rootNode = qdb_->treeRoot();
if (!rootNode)
return;
writer.writeStartElement("toc");
writer.writeStartElement("section");
- const Node* node = tree->findDocNodeByTitle(project.indexTitle);
+ const Node* node = qdb_->findDocNodeByTitle(project.indexTitle);
if (node == 0)
- node = tree->findNode(QStringList("index.html"));
+ node = qdb_->findNode(QStringList("index.html"));
QString indexPath;
if (node)
indexPath = gen_->fullDocumentLocation(node,true);
if (subproject.type == QLatin1String("manual")) {
- const DocNode *indexPage = tree->findDocNodeByTitle(subproject.indexTitle);
+ const DocNode *indexPage = qdb_->findDocNodeByTitle(subproject.indexTitle);
if (indexPage) {
Text indexBody = indexPage->doc().body();
const Atom *atom = indexBody.firstAtom();
if (sectionStack.top() > 0)
writer.writeEndElement(); // section
- const DocNode *page = tree->findDocNodeByTitle(atom->string());
+ const DocNode *page = qdb_->findDocNodeByTitle(atom->string());
writer.writeStartElement("section");
QString indexPath = gen_->fullDocumentLocation(page,true);
writer.writeAttribute("ref", indexPath);
if (!name.isEmpty()) {
writer.writeStartElement("section");
- QString indexPath = gen_->fullDocumentLocation(tree->findDocNodeByTitle(subproject.indexTitle),true);
+ QString indexPath = gen_->fullDocumentLocation(qdb_->findDocNodeByTitle(subproject.indexTitle),true);
writer.writeAttribute("ref", indexPath);
writer.writeAttribute("title", subproject.title);
project.files.insert(indexPath);
if (!nextTitle.isEmpty() &&
node->links().value(Node::ContentsLink).first.isEmpty()) {
- DocNode *nextPage = const_cast<DocNode *>(tree->findDocNodeByTitle(nextTitle));
+ DocNode *nextPage = const_cast<DocNode *>(qdb_->findDocNodeByTitle(nextTitle));
// Write the contents node.
writeNode(project, writer, node);
nextTitle = nextPage->links().value(Node::NextLink).first;
if (nextTitle.isEmpty() || visited.contains(nextTitle))
break;
- nextPage = const_cast<DocNode *>(tree->findDocNodeByTitle(nextTitle));
+ nextPage = const_cast<DocNode *>(qdb_->findDocNodeByTitle(nextTitle));
visited.insert(nextTitle);
}
break;
QT_BEGIN_NAMESPACE
-class Tree;
+class QDocDatabase;
class Generator;
typedef QPair<QString, const Node*> QStringNodePair;
Generator* g);
void addExtraFile(const QString &file);
void addExtraFiles(const QSet<QString> &files);
- void generate(const Tree *t);
+ void generate();
private:
void generateProject(HelpProject &project);
void writeNode(HelpProject &project, QXmlStreamWriter &writer, const Node *node);
void readSelectors(SubProject &subproject, const QStringList &selectors);
- const Tree *tree;
+ QDocDatabase* qdb_;
Generator* gen_;
QString outputDir;
#include "helpprojectwriter.h"
#include "htmlgenerator.h"
#include "node.h"
+#include "qdocdatabase.h"
#include "separator.h"
#include "tree.h"
#include <ctype.h>
}
}
-
+/*!
+ Constructs the HTML output generator.
+ */
HtmlGenerator::HtmlGenerator()
: helpProjectWriter(0),
- inLink(false),
inObsoleteLink(false),
- inContents(false),
- inSectionHeading(false),
- inTableHeader(false),
- numTableRows(0),
- threeColumnEnumValueTable(true),
funcLeftParen("\\S(\\()"),
obsoleteLinks(false)
{
}
/*!
- The destructor deletes the instance of HelpProjectWriter.
+ Destroys the HTML output generator. Deletes the singleton
+ instance of HelpProjectWriter.
*/
HtmlGenerator::~HtmlGenerator()
{
delete helpProjectWriter;
}
+/*!
+ Initializes the HTML output generator's data structures
+ from the configuration class \a config.
+ */
void HtmlGenerator::initializeGenerator(const Config &config)
{
static const struct {
codeIndent = config.getInt(CONFIG_CODEINDENT);
- helpProjectWriter = new HelpProjectWriter(config,
- project.toLower() + ".qhp",
- this);
+ helpProjectWriter = new HelpProjectWriter(config, project.toLower() + ".qhp", this);
// Documentation template handling
- headerScripts = config.getString(HtmlGenerator::format() + Config::dot +
- CONFIG_HEADERSCRIPTS);
- headerStyles = config.getString(HtmlGenerator::format() +
- Config::dot +
- CONFIG_HEADERSTYLES);
+ headerScripts = config.getString(HtmlGenerator::format() + Config::dot + CONFIG_HEADERSCRIPTS);
+ headerStyles = config.getString(HtmlGenerator::format() + Config::dot + CONFIG_HEADERSTYLES);
QString prefix = CONFIG_QHP + Config::dot + "Qt" + Config::dot;
manifestDir = "qthelp://" + config.getString(prefix + "namespace");
}
}
+/*!
+ Gracefully terminates the HTML output generator.
+ */
void HtmlGenerator::terminateGenerator()
{
Generator::terminateGenerator();
}
/*!
- This is where the HTML files are written.
- \note The HTML file generation is done in the base class,
- PageGenerator::generateTree().
+ Traverses the database generating all the HTML documentation.
*/
-void HtmlGenerator::generateTree(Tree *tree)
+void HtmlGenerator::generateTree()
{
- tree_ = tree;
- nonCompatClasses.clear();
- mainClasses.clear();
- compatClasses.clear();
- obsoleteClasses.clear();
- moduleClassMap.clear();
- moduleNamespaceMap.clear();
- funcIndex.clear();
- legaleseTexts.clear();
- serviceClasses.clear();
- qmlClasses.clear();
-
- findAllClasses(tree->root());
- findAllFunctions(tree->root());
- findAllLegaleseTexts(tree->root());
- findAllNamespaces(tree->root());
- findAllSince(tree->root());
-
- Generator::generateTree(tree);
- //reportOrphans(tree->root());
+ qdb_->buildCollections();
+ Generator::generateTree();
generateCollisionPages();
QString fileBase = project.toLower().simplified().replace(QLatin1Char(' '), QLatin1Char('-'));
generateIndex(fileBase, projectUrl, projectDescription);
- helpProjectWriter->generate(tree_);
+ helpProjectWriter->generate();
generateManifestFiles();
}
-void HtmlGenerator::startText(const Node * /* relative */,
- CodeMarker * /* marker */)
-{
- inLink = false;
- inContents = false;
- inSectionHeading = false;
- inTableHeader = false;
- numTableRows = 0;
- threeColumnEnumValueTable = true;
- link.clear();
- sectionNumber.clear();
-}
-
/*!
Generate html from an instance of Atom.
*/
-int HtmlGenerator::generateAtom(const Atom *atom,
- const Node *relative,
- CodeMarker *marker)
+int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMarker *marker)
{
int skipAhead = 0;
static bool in_para = false;
case Atom::AbstractRight:
break;
case Atom::AutoLink:
- if (!inLink && !inContents && !inSectionHeading) {
+ if (!inLink_ && !inContents_ && !inSectionHeading_) {
const Node *node = 0;
- QString link = getLink(atom, relative, marker, &node);
+ QString link = getLink(atom, relative, &node);
if (!link.isEmpty()) {
- beginLink(link, node, relative, marker);
- generateLink(atom, relative, marker);
+ beginLink(link, node, relative);
+ generateLink(atom, marker);
endLink();
}
else {
// now widely used to write teletype text. As a result, text marked
// with the \c command is not passed to a code marker.
out() << formattingLeftMap()[ATOM_FORMATTING_TELETYPE];
- if (inLink) {
+ if (inLink_) {
out() << protectEnc(plainCode(atom->string()));
}
else {
break;
case Atom::Code:
out() << "<pre class=\"cpp\">"
- << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
- marker,relative))
+ << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),relative))
<< "</pre>\n";
break;
case Atom::Qml:
out() << "<pre class=\"qml\">"
- << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
- marker,relative))
+ << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),relative))
<< "</pre>\n";
break;
case Atom::JavaScript:
out() << "<pre class=\"js\">"
- << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
- marker,relative))
+ << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),relative))
<< "</pre>\n";
break;
case Atom::CodeNew:
out() << "<p>you can rewrite it as</p>\n"
<< "<pre class=\"cpp\">"
- << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
- marker,relative))
+ << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),relative))
<< "</pre>\n";
break;
case Atom::CodeOld:
}
break;
case Atom::AnnotatedList:
- {
- QList<Node*> values = tree_->groups().values(atom->string());
- NodeMap nodeMap;
- for (int i = 0; i < values.size(); ++i) {
- const Node* n = values.at(i);
- if ((n->status() != Node::Internal) && (n->access() != Node::Private)) {
- nodeMap.insert(n->nameForLists(),n);
- }
+ {
+ NodeMap nodeMap;
+ qdb_->getGroup(atom->string(), nodeMap);
+ generateAnnotatedList(relative, marker, nodeMap);
}
- generateAnnotatedList(relative, marker, nodeMap);
- }
break;
case Atom::GeneratedList:
if (atom->string() == "annotatedclasses") {
- generateAnnotatedList(relative, marker, nonCompatClasses);
+ generateAnnotatedList(relative, marker, qdb_->getCppClasses());
}
else if (atom->string() == "classes") {
- generateCompactList(relative, marker, nonCompatClasses, true);
+ generateCompactList(relative, qdb_->getCppClasses(), true);
}
else if (atom->string() == "qmlclasses") {
- generateCompactList(relative, marker, qmlClasses, true);
+ generateCompactList(relative, qdb_->getQmlTypes(), true);
}
else if (atom->string().contains("classesbymodule")) {
QString arg = atom->string().trimmed();
- QString moduleName = atom->string().mid(atom->string().indexOf(
- "classesbymodule") + 15).trimmed();
- if (moduleClassMap.contains(moduleName))
- generateAnnotatedList(relative, marker, moduleClassMap[moduleName]);
+ QString moduleName = atom->string().mid(atom->string().indexOf("classesbymodule") + 15).trimmed();
+ QDocDatabase* qdb = QDocDatabase::qdocDB();
+ DocNode* dn = qdb->findModule(moduleName);
+ if (dn) {
+ NodeMap m;
+ dn->getMemberClasses(m);
+ if (!m.isEmpty()) {
+ generateAnnotatedList(relative, marker, m);
+ }
+ }
}
else if (atom->string().contains("classesbyedition")) {
-
QString arg = atom->string().trimmed();
- QString editionName = atom->string().mid(atom->string().indexOf(
- "classesbyedition") + 16).trimmed();
-
+ QString editionName = atom->string().mid(atom->string().indexOf("classesbyedition") + 16).trimmed();
if (editionModuleMap.contains(editionName)) {
-
+ QDocDatabase* qdb = QDocDatabase::qdocDB();
// Add all classes in the modules listed for that edition.
NodeMap editionClasses;
- foreach (const QString &moduleName, editionModuleMap[editionName]) {
- if (moduleClassMap.contains(moduleName))
- editionClasses.unite(moduleClassMap[moduleName]);
+ DocNodeMap::const_iterator i = qdb->modules().begin();
+ while (i != qdb->modules().end()) {
+ NodeMap m;
+ DocNode* dn = i.value();
+ dn->getMemberClasses(m);
+ if (!m.isEmpty())
+ editionClasses.unite(m);
+ m.clear();
+ ++i;
}
// Add additional groups and remove groups of classes that
// should be excluded from the edition.
- QMultiMap <QString, Node *> groups = tree_->groups();
+ const NodeMultiMap& groups = qdb_->groups();
foreach (const QString &groupName, editionGroupMap[editionName]) {
QList<Node *> groupClasses;
if (groupName.startsWith(QLatin1Char('-'))) {
}
}
else if (atom->string() == "classhierarchy") {
- generateClassHierarchy(relative, marker, nonCompatClasses);
+ generateClassHierarchy(relative, qdb_->getCppClasses());
}
else if (atom->string() == "compatclasses") {
- generateCompactList(relative, marker, compatClasses, false);
+ generateCompactList(relative, qdb_->getCompatibilityClasses(), false);
}
else if (atom->string() == "obsoleteclasses") {
- generateCompactList(relative, marker, obsoleteClasses, false);
+ generateCompactList(relative, qdb_->getObsoleteClasses(), false);
}
else if (atom->string() == "functionindex") {
- generateFunctionIndex(relative, marker);
+ generateFunctionIndex(relative);
}
else if (atom->string() == "legalese") {
generateLegaleseList(relative, marker);
}
else if (atom->string() == "mainclasses") {
- generateCompactList(relative, marker, mainClasses, true);
+ generateCompactList(relative, qdb_->getMainClasses(), true);
}
else if (atom->string() == "services") {
- generateCompactList(relative, marker, serviceClasses, false);
+ generateCompactList(relative, qdb_->getServiceClasses(), false);
}
else if (atom->string() == "overviews") {
- generateOverviewList(relative, marker);
+ generateOverviewList(relative);
}
else if (atom->string() == "namespaces") {
- generateAnnotatedList(relative, marker, namespaceIndex);
+ generateAnnotatedList(relative, marker, qdb_->getNamespaces());
}
else if (atom->string() == "related") {
const DocNode *dn = static_cast<const DocNode *>(relative);
- if (dn && !dn->groupMembers().isEmpty()) {
+ if (dn && !dn->members().isEmpty()) {
NodeMap groupMembersMap;
- foreach (const Node *node, dn->groupMembers()) {
+ foreach (const Node *node, dn->members()) {
if (node->type() == Node::Document)
- groupMembersMap[fullName(node, relative, marker)] = node;
+ groupMembersMap[node->fullName(relative)] = node;
}
generateAnnotatedList(dn, marker, groupMembersMap);
}
}
else if (atom->string() == "relatedinline") {
const DocNode *dn = static_cast<const DocNode *>(relative);
- if (dn && !dn->groupMembers().isEmpty()) {
+ if (dn && !dn->members().isEmpty()) {
// Reverse the list into the original scan order.
// Should be sorted. But on what? It may not be a
// regular class or page definition.
QList<const Node *> list;
- foreach (const Node *node, dn->groupMembers())
+ foreach (const Node *node, dn->members())
list.prepend(node);
foreach (const Node *node, list)
generateBody(node, marker);
break;
case Atom::SinceList:
{
- NewSinceMaps::const_iterator nsmap;
- nsmap = newSinceMaps.constFind(atom->string());
- NewClassMaps::const_iterator ncmap;
- ncmap = newClassMaps.constFind(atom->string());
- NewClassMaps::const_iterator nqcmap;
- nqcmap = newQmlClassMaps.constFind(atom->string());
-
- if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) {
+ const NodeMultiMap& nsmap = qdb_->getSinceMap(atom->string());
+ const NodeMap& ncmap = qdb_->getClassMap(atom->string());
+ const NodeMap& nqcmap = qdb_->getQmlTypeMap(atom->string());
+
+ if (!nsmap.isEmpty()) {
QList<Section> sections;
QList<Section>::ConstIterator s;
for (int i=0; i<LastSinceType; ++i)
sections.append(Section(sinceTitle(i),QString(),QString(),QString()));
- NodeMultiMap::const_iterator n = nsmap.value().constBegin();
-
- while (n != nsmap.value().constEnd()) {
-
+ NodeMultiMap::const_iterator n = nsmap.constBegin();
+ while (n != nsmap.constEnd()) {
const Node* node = n.value();
switch (node->type()) {
case Node::Document:
++n;
}
- /*
- First generate the table of contents.
- */
out() << "<ul>\n";
s = sections.constBegin();
while (s != sections.constEnd()) {
<< "\"></a>\n";
out() << "<h3>" << protectEnc((*s).name) << "</h3>\n";
if (idx == Class)
- generateCompactList(0, marker, ncmap.value(), false, QString("Q"));
+ generateCompactList(0, ncmap, false, QString("Q"));
else if (idx == QmlClass)
- generateCompactList(0, marker, nqcmap.value(), false, QString("Q"));
+ generateCompactList(0, nqcmap, false, QString("Q"));
else if (idx == MemberFunction) {
ParentMaps parentmaps;
ParentMaps::iterator pmap;
out() << "<a href=\""
<< linkForNode(pmap.key(), 0)
<< "\">";
- QStringList pieces = fullName(pmap.key(), 0, marker).split("::");
+ QStringList pieces = pmap.key()->fullName().split("::");
out() << protectEnc(pieces.last());
out() << "</a>" << ":</p>\n";
case Atom::Link:
{
const Node *node = 0;
- QString myLink = getLink(atom, relative, marker, &node);
+ QString myLink = getLink(atom, relative, &node);
if (myLink.isEmpty()) {
myLink = getCollisionLink(atom);
if (myLink.isEmpty()) {
else
node = 0;
}
- beginLink(myLink, node, relative, marker);
+ beginLink(myLink, node, relative);
skipAhead = 1;
}
break;
case Atom::LinkNode:
{
const Node *node = CodeMarker::nodeForString(atom->string());
- beginLink(linkForNode(node, relative), node, relative, marker);
+ beginLink(linkForNode(node, relative), node, relative);
skipAhead = 1;
}
break;
out() << "<dl>\n";
}
else if (atom->string() == ATOM_LIST_VALUE) {
- threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
- if (threeColumnEnumValueTable) {
+ threeColumnEnumValueTable_ = isThreeColumnEnumValueTable(atom);
+ if (threeColumnEnumValueTable_) {
out() << "<table class=\"valuelist\">";
- if (++numTableRows % 2 == 1)
+ if (++numTableRows_ % 2 == 1)
out() << "<tr valign=\"top\" class=\"odd\">";
else
out() << "<tr valign=\"top\" class=\"even\">";
out() << "<dd>";
}
else if (atom->string() == ATOM_LIST_VALUE) {
- if (threeColumnEnumValueTable) {
+ if (threeColumnEnumValueTable_) {
out() << "</td><td class=\"topAlign\">";
if (matchAhead(atom, Atom::ListItemRight))
out() << " ";
break;
case Atom::SectionHeadingLeft:
out() << "<h" + QString::number(atom->string().toInt() + hOffset(relative)) + QLatin1Char('>');
- inSectionHeading = true;
+ inSectionHeading_ = true;
break;
case Atom::SectionHeadingRight:
out() << "</h" + QString::number(atom->string().toInt() + hOffset(relative)) + ">\n";
- inSectionHeading = false;
+ inSectionHeading_ = false;
break;
case Atom::SidebarLeft:
break;
case Atom::SidebarRight:
break;
case Atom::String:
- if (inLink && !inContents && !inSectionHeading) {
- generateLink(atom, relative, marker);
+ if (inLink_ && !inContents_ && !inSectionHeading_) {
+ generateLink(atom, marker);
}
else {
out() << protectEnc(atom->string());
if (!width.isEmpty())
out() << " width=\"" << width << "\"";
out() << ">\n ";
- numTableRows = 0;
+ numTableRows_ = 0;
}
break;
case Atom::TableRight:
break;
case Atom::TableHeaderLeft:
out() << "<thead><tr class=\"qt-style\">";
- inTableHeader = true;
+ inTableHeader_ = true;
break;
case Atom::TableHeaderRight:
out() << "</tr>";
}
else {
out() << "</thead>\n";
- inTableHeader = false;
+ inTableHeader_ = false;
}
break;
case Atom::TableRowLeft:
if (!atom->string().isEmpty())
out() << "<tr " << atom->string() << '>';
- else if (++numTableRows % 2 == 1)
+ else if (++numTableRows_ % 2 == 1)
out() << "<tr valign=\"top\" class=\"odd\">";
else
out() << "<tr valign=\"top\" class=\"even\">";
break;
case Atom::TableItemLeft:
{
- if (inTableHeader)
+ if (inTableHeader_)
out() << "<th ";
else
out() << "<td ";
}
}
}
- if (inTableHeader)
+ if (inTableHeader_)
out() << '>';
else {
out() << '>';
}
break;
case Atom::TableItemRight:
- if (inTableHeader)
+ if (inTableHeader_)
out() << "</th>";
else {
out() << "</td>";
QString rawTitle;
QString fullTitle;
if (inner->type() == Node::Namespace) {
- rawTitle = marker->plainName(inner);
- fullTitle = marker->plainFullName(inner);
+ rawTitle = inner->plainName();
+ fullTitle = inner->plainFullName();
title = rawTitle + " Namespace";
}
else if (inner->type() == Node::Class) {
classe = static_cast<ClassNode*>(inner);
- rawTitle = marker->plainName(inner);
- fullTitle = marker->plainFullName(inner);
+ rawTitle = inner->plainName();
+ fullTitle = inner->plainFullName();
title = rawTitle + " Class";
}
Text subtitleText;
if (rawTitle != fullTitle)
- subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")"
- << Atom(Atom::LineBreak);
+ subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")" << Atom(Atom::LineBreak);
generateHeader(title, inner, marker);
sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
if (!s->inherited.isEmpty()) {
out() << "<ul>\n";
- generateSectionInheritedList(*s, inner, marker);
+ generateSectionInheritedList(*s, inner);
out() << "</ul>\n";
}
}
s = sections.constBegin();
while (s != sections.constEnd()) {
if (s->members.isEmpty() && !s->inherited.isEmpty())
- generateSectionInheritedList(*s, inner, marker);
+ generateSectionInheritedList(*s, inner);
++s;
}
out() << "</ul>\n";
generateDetailedMember(*m, inner, marker);
else {
out() << "<h3> class ";
- generateFullName(*m, inner, marker);
+ generateFullName(*m, inner);
out() << "</h3>";
generateBrief(*m, marker, inner);
}
generateStatus(dn, marker);
generateSince(dn, marker);
- if (moduleNamespaceMap.contains(dn->name())) {
+ NodeMap nm;
+ dn->getMemberNamespaces(nm);
+ if (!nm.isEmpty()) {
out() << "<a name=\"" << registerRef("namespaces") << "\"></a>" << divNavTop << '\n';
out() << "<h2>Namespaces</h2>\n";
- generateAnnotatedList(dn, marker, moduleNamespaceMap[dn->name()]);
+ generateAnnotatedList(dn, marker, nm);
}
- if (moduleClassMap.contains(dn->name())) {
+ nm.clear();
+ dn->getMemberClasses(nm);
+ if (!nm.isEmpty()) {
out() << "<a name=\"" << registerRef("classes") << "\"></a>" << divNavTop << '\n';
out() << "<h2>Classes</h2>\n";
- generateAnnotatedList(dn, marker, moduleClassMap[dn->name()]);
+ generateAnnotatedList(dn, marker, nm);
}
+ nm.clear();
}
else if (dn->subType() == Node::HeaderFile) {
// Generate brief text and status for modules.
generateAlsoList(dn, marker);
generateExtractionMark(dn, EndMark);
- if ((dn->subType() == Node::Group) && !dn->groupMembers().isEmpty()) {
+ if ((dn->subType() == Node::Group) && !dn->members().isEmpty()) {
NodeMap groupMembersMap;
- foreach (const Node *node, dn->groupMembers()) {
+ foreach (const Node *node, dn->members()) {
if (node->type() == Node::Class || node->type() == Node::Namespace)
groupMembersMap[node->name()] = node;
}
generateAnnotatedList(dn, marker, groupMembersMap);
}
- else if ((dn->subType() == Node::QmlModule) && !dn->qmlModuleMembers().isEmpty()) {
+ else if ((dn->subType() == Node::QmlModule) && !dn->members().isEmpty()) {
NodeMap qmlModuleMembersMap;
- foreach (const Node* node, dn->qmlModuleMembers()) {
+ foreach (const Node* node, dn->members()) {
if (node->type() == Node::Document && node->subType() == Node::QmlClass)
qmlModuleMembersMap[node->name()] = node;
}
if (node && !node->doc().location().isEmpty())
out() << "<!-- " << node->doc().location().fileName() << " -->\n";
- QString shortVersion = tree_->version();
+ QString shortVersion = qdb_->version();
if (shortVersion.count(QChar('.')) == 2)
shortVersion.truncate(shortVersion.lastIndexOf(QChar('.')));
if (!project.isEmpty())
generateMacRef(node, marker);
#endif
- out() << QString(postHeader).replace("\\" + COMMAND_VERSION, tree_->version());
+ out() << QString(postHeader).replace("\\" + COMMAND_VERSION, qdb_->version());
generateBreadCrumbs(title,node,marker);
- out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, tree_->version());
+ out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, qdb_->version());
navigationLinks.clear();
if (node->links().contains(Node::PreviousLink)) {
linkPair = node->links()[Node::PreviousLink];
- linkNode = findNodeForTarget(linkPair.first, node, marker);
+ linkNode = qdb_->findNodeForTarget(linkPair.first, node);
+ if (!linkNode)
+ node->doc().location().warning(tr("Cannot link to '%1'").arg(linkPair.first));
if (!linkNode || linkNode == node)
anchorPair = linkPair;
else
}
if (node->links().contains(Node::NextLink)) {
linkPair = node->links()[Node::NextLink];
- linkNode = findNodeForTarget(linkPair.first, node, marker);
+ linkNode = qdb_->findNodeForTarget(linkPair.first, node);
+ if (!linkNode)
+ node->doc().location().warning(tr("Cannot link to '%1'").arg(linkPair.first));
if (!linkNode || linkNode == node)
anchorPair = linkPair;
else
}
if (node->links().contains(Node::StartLink)) {
linkPair = node->links()[Node::StartLink];
- linkNode = findNodeForTarget(linkPair.first, node, marker);
+ linkNode = qdb_->findNodeForTarget(linkPair.first, node);
+ if (!linkNode)
+ node->doc().location().warning(tr("Cannot link to '%1'").arg(linkPair.first));
if (!linkNode || linkNode == node)
anchorPair = linkPair;
else
if (node && !node->links().empty())
out() << "<p class=\"naviNextPrevious footerNavi\">\n" << navigationLinks << "</p>\n";
- out() << QString(footer).replace("\\" + COMMAND_VERSION, tree_->version())
- << QString(address).replace("\\" + COMMAND_VERSION, tree_->version());
+ out() << QString(footer).replace("\\" + COMMAND_VERSION, qdb_->version())
+ << QString(address).replace("\\" + COMMAND_VERSION, qdb_->version());
out() << "</body>\n";
out() << "</html>\n";
out() << "<pre class=\"cpp\">"
<< trimmedTrailing(highlightedCode(indent(codeIndent,
marker->markedUpIncludes(inner->includes())),
- marker,inner))
+ inner))
<< "</pre>";
}
}
int detailsBase = 0;
// disable nested links in table of contents
- inContents = true;
- inLink = true;
+ inContents_ = true;
+ inLink_ = true;
out() << "<div class=\"toc\">\n";
out() << "<h3><a name=\"toc\">Contents</a></h3>\n";
out() << "<ul>\n";
if (node->subType() == Node::Module) {
- if (moduleNamespaceMap.contains(node->name())) {
+ if (node->hasNamespaces()) {
out() << "<li class=\"level"
<< sectionNumber.size()
<< "\"><a href=\"#"
<< registerRef("namespaces")
<< "\">Namespaces</a></li>\n";
}
- if (moduleClassMap.contains(node->name())) {
+ if (node->hasClasses()) {
out() << "<li class=\"level"
<< sectionNumber.size()
<< "\"><a href=\"#"
}
out() << "</ul>\n";
out() << "</div>\n";
- inContents = false;
- inLink = false;
+ inContents_ = false;
+ inLink_ = false;
}
QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner,
generateHeader(title, inner, marker);
generateTitle(title, Text(), SmallSubTitle, inner, marker);
out() << "<p>This is the complete list of members for ";
- generateFullName(inner, 0, marker);
+ generateFullName(inner, 0);
out() << ", including inherited members.</p>\n";
Section section = sections.first();
generateHeader(title, qml_cn, marker);
generateTitle(title, Text(), SmallSubTitle, qml_cn, marker);
out() << "<p>This is the complete list of members for ";
- generateFullName(qml_cn, 0, marker);
+ generateFullName(qml_cn, 0);
out() << ", including inherited members.</p>\n";
Section section = sections.first();
return fileName;
}
-void HtmlGenerator::generateClassHierarchy(const Node *relative,
- CodeMarker *marker,
- const QMap<QString,const Node*> &classMap)
+void HtmlGenerator::generateClassHierarchy(const Node *relative, const NodeMap& classMap)
{
if (classMap.isEmpty())
return;
const ClassNode *child =
static_cast<const ClassNode *>(*stack.top().constBegin());
out() << "<li>";
- generateFullName(child, relative, marker);
+ generateFullName(child, relative);
out() << "</li>\n";
stack.top().erase(stack.top().begin());
else
out() << "<tr class=\"even topAlign\">";
out() << "<td class=\"tblName\"><p>";
- generateFullName(node, relative, marker);
+ generateFullName(node, relative);
out() << "</p></td>";
if (!(node->type() == Node::Document)) {
the name of the first and last classes in \a classMap.
*/
void HtmlGenerator::generateCompactList(const Node *relative,
- CodeMarker *marker,
const NodeMap &classMap,
bool includeAlphabet,
QString commonPrefix)
Output a <div> element to contain all the <dl> elements.
*/
out() << "<div class=\"flowListDiv\">\n";
- numTableRows = 0;
+ numTableRows_ = 0;
int curParNr = 0;
int curParOffset = 0;
if (curParOffset == 0) {
if (i > 0)
out() << "</dl>\n";
- if (++numTableRows % 2 == 1)
+ if (++numTableRows_ % 2 == 1)
out() << "<dl class=\"flowList odd\">";
else
out() << "<dl class=\"flowList even\">";
if (it.value()->subType() == Node::QmlClass)
pieces << it.value()->name();
else
- pieces = fullName(it.value(), relative, marker).split("::");
+ pieces = it.value()->fullName(relative).split("::");
out() << protectEnc(pieces.last());
out() << "</a>";
if (pieces.size() > 1) {
out() << " (";
- generateFullName(it.value()->parent(), relative, marker);
+ generateFullName(it.value()->parent(), relative);
out() << ')';
}
}
out() << "</div>\n";
}
-void HtmlGenerator::generateFunctionIndex(const Node *relative,
- CodeMarker *marker)
+void HtmlGenerator::generateFunctionIndex(const Node *relative)
{
out() << "<p class=\"centerAlign functionIndex\"><b>";
for (int i = 0; i < 26; i++) {
char currentLetter;
out() << "<ul>\n";
+ NodeMapMap funcIndex = qdb_->getFunctionIndex();
QMap<QString, NodeMap >::ConstIterator f = funcIndex.constBegin();
while (f != funcIndex.constEnd()) {
out() << "<li>";
NodeMap::ConstIterator s = (*f).constBegin();
while (s != (*f).constEnd()) {
out() << ' ';
- generateFullName((*s)->parent(), relative, marker, *s);
+ generateFullName((*s)->parent(), relative, *s);
++s;
}
out() << "</li>";
out() << "</ul>\n";
}
-void HtmlGenerator::generateLegaleseList(const Node *relative,
- CodeMarker *marker)
+void HtmlGenerator::generateLegaleseList(const Node *relative, CodeMarker *marker)
{
+ TextToNodeMap& legaleseTexts = qdb_->getLegaleseTexts();
QMap<Text, const Node *>::ConstIterator it = legaleseTexts.constBegin();
while (it != legaleseTexts.constEnd()) {
Text text = it.key();
out() << "<ul>\n";
do {
out() << "<li>";
- generateFullName(it.value(), relative, marker);
+ generateFullName(it.value(), relative);
out() << "</li>\n";
++it;
} while (it != legaleseTexts.constEnd() && it.key() == text);
marked.remove("<@type>");
marked.remove("</@type>");
}
- out() << highlightedCode(marked, marker, relative, false, node);
+ out() << highlightedCode(marked, relative, false, node);
}
-void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* marker */)
+void HtmlGenerator::generateOverviewList(const Node *relative)
{
QMap<const DocNode *, QMap<QString, DocNode *> > docNodeMap;
QMap<QString, const DocNode *> groupTitlesMap;
QMap<QString, DocNode *> uncategorizedNodeMap;
QRegExp singleDigit("\\b([0-9])\\b");
- const NodeList children = tree_->root()->childNodes();
+ const NodeList children = qdb_->treeRoot()->childNodes();
foreach (Node *child, children) {
if (child->type() == Node::Document && child != relative) {
DocNode *docNode = static_cast<DocNode *>(child);
if (isGroupPage) {
// If we encounter a group definition page, we add all
// the pages in that group to the list for that group.
- foreach (Node *member, docNode->groupMembers()) {
+ foreach (Node *member, docNode->members()) {
if (member->type() != Node::Document)
continue;
DocNode *page = static_cast<DocNode *>(member);
else if (!isGroupPage) {
// If we encounter a page that belongs to a group then
// we add that page to the list for that group.
- const DocNode* gn = tree_->findGroupNode(QStringList(group));
+ const DocNode* gn = qdb_->findGroupNode(QStringList(group));
if (gn)
docNodeMap[gn].insert(sortKey, docNode);
}
if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
out() << "<ul>\n";
- generateSectionInheritedList(section, relative, marker);
+ generateSectionInheritedList(section, relative);
out() << "</ul>\n";
}
}
-void HtmlGenerator::generateSectionInheritedList(const Section& section,
- const Node *relative,
- CodeMarker *marker)
+void HtmlGenerator::generateSectionInheritedList(const Section& section, const Node *relative)
{
QList<QPair<InnerNode *, int> >::ConstIterator p = section.inherited.constBegin();
while (p != section.inherited.constEnd()) {
}
out() << " inherited from <a href=\"" << fileName((*p).first)
<< '#' << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
- << protectEnc(marker->plainFullName((*p).first, relative))
+ << protectEnc((*p).first->plainFullName(relative))
<< "</a></li>\n";
++p;
}
marked.remove("</@type>");
}
- out() << highlightedCode(marked, marker, relative, alignNames);
+ out() << highlightedCode(marked, relative, alignNames);
}
QString HtmlGenerator::highlightedCode(const QString& markedCode,
- CodeMarker* marker,
const Node* relative,
bool alignNames,
const Node* self)
i += 2;
if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) {
- const Node* n = marker->resolveTarget(par1.toString(),
- tree_,
- relative);
+ const Node* n = qdb_->resolveTarget(par1.toString(), relative);
QString link = linkForNode(n, relative);
addLink(link, arg, &html);
par1 = QStringRef();
bool handled = false;
if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) {
par1 = QStringRef();
- const Node* n = marker->resolveTarget(arg.toString(), tree_, relative, self);
+ const Node* n = qdb_->resolveTarget(arg.toString(), relative, self);
html += QLatin1String("<span class=\"type\">");
if (n && n->subType() == Node::QmlBasicType) {
if (relative && relative->subType() == Node::QmlClass)
}
else if (parseArg(src, headerTag, &i, srcSize, &arg, &par1)) {
par1 = QStringRef();
- const Node* n = marker->resolveTarget(arg.toString(), tree_, relative);
+ const Node* n = qdb_->resolveTarget(arg.toString(), relative);
addLink(linkForNode(n,relative), arg, &html);
handled = true;
}
else if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) {
par1 = QStringRef();
- const Node* n = marker->resolveTarget(arg.toString(), tree_, relative);
+ const Node* n = qdb_->resolveTarget(arg.toString(), relative);
addLink(linkForNode(n,relative), arg, &html);
handled = true;
}
return html;
}
-void HtmlGenerator::generateLink(const Atom* atom,
- const Node* /* relative */,
- CodeMarker* marker)
+void HtmlGenerator::generateLink(const Atom* atom, CodeMarker* marker)
{
static QRegExp camelCase("[A-Z][A-Z][a-z]|[a-z][A-Z0-9]|_");
// hack for C++: move () outside of link
int k = funcLeftParen.pos(1);
out() << protectEnc(atom->string().left(k));
- if (link.isEmpty()) {
+ if (link_.isEmpty()) {
if (showBrokenLinks)
out() << "</i>";
} else {
out() << "</a>";
}
- inLink = false;
+ inLink_ = false;
out() << protectEnc(atom->string().mid(k));
} else {
out() << protectEnc(atom->string());
}
}
-void HtmlGenerator::generateFullName(const Node *apparentNode,
- const Node *relative,
- CodeMarker *marker,
- const Node *actualNode)
+void HtmlGenerator::generateFullName(const Node *apparentNode, const Node *relative, const Node *actualNode)
{
if (actualNode == 0)
actualNode = apparentNode;
}
}
out() << "\">";
- out() << protectEnc(fullName(apparentNode, relative, marker));
+ out() << protectEnc(apparentNode->fullName(relative));
out() << "</a>";
}
generateExtractionMark(node, EndMark);
}
-void HtmlGenerator::findAllClasses(const InnerNode *node)
-{
- NodeList::const_iterator c = node->childNodes().constBegin();
- while (c != node->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private && (*c)->url().isEmpty()) {
- if ((*c)->type() == Node::Class && !(*c)->doc().isEmpty()) {
- QString className = (*c)->name();
- if ((*c)->parent() &&
- (*c)->parent()->type() == Node::Namespace &&
- !(*c)->parent()->name().isEmpty())
- className = (*c)->parent()->name()+"::"+className;
-
- if (!(static_cast<const ClassNode *>(*c))->hideFromMainList()) {
- if ((*c)->status() == Node::Compat) {
- compatClasses.insert(className, *c);
- }
- else if ((*c)->status() == Node::Obsolete) {
- obsoleteClasses.insert(className, *c);
- }
- else {
- nonCompatClasses.insert(className, *c);
- if ((*c)->status() == Node::Main)
- mainClasses.insert(className, *c);
- }
- }
-
- QString moduleName = (*c)->moduleName();
- if (moduleName == "Qt3SupportLight") {
- moduleClassMap[moduleName].insert((*c)->name(), *c);
- moduleName = "Qt3Support";
- }
- if (!moduleName.isEmpty())
- moduleClassMap[moduleName].insert((*c)->name(), *c);
-
- QString serviceName =
- (static_cast<const ClassNode *>(*c))->serviceName();
- if (!serviceName.isEmpty())
- serviceClasses.insert(serviceName, *c);
- }
- else if ((*c)->type() == Node::Document &&
- (*c)->subType() == Node::QmlClass &&
- !(*c)->doc().isEmpty()) {
- QString qmlClassName = (*c)->name();
- /*
- Remove the "QML:" prefix, if present.
- It shouldn't be present anymore.
- */
- if (qmlClassName.startsWith(QLatin1String("QML:")))
- qmlClasses.insert(qmlClassName.mid(4),*c);
- else
- qmlClasses.insert(qmlClassName,*c);
- }
- else if ((*c)->isInnerNode()) {
- findAllClasses(static_cast<InnerNode *>(*c));
- }
- }
- ++c;
- }
-}
-
-void HtmlGenerator::findAllFunctions(const InnerNode *node)
-{
- NodeList::ConstIterator c = node->childNodes().constBegin();
- while (c != node->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private) {
- if ((*c)->isInnerNode() && (*c)->url().isEmpty()) {
- findAllFunctions(static_cast<const InnerNode *>(*c));
- }
- else if ((*c)->type() == Node::Function) {
- const FunctionNode *func = static_cast<const FunctionNode *>(*c);
- if ((func->status() > Node::Obsolete) &&
- !func->isInternal() &&
- (func->metaness() != FunctionNode::Ctor) &&
- (func->metaness() != FunctionNode::Dtor)) {
- funcIndex[(*c)->name()].insert((*c)->parent()->fullDocumentName(), *c);
- }
- }
- }
- ++c;
- }
-}
-
-void HtmlGenerator::findAllLegaleseTexts(const InnerNode *node)
-{
- NodeList::ConstIterator c = node->childNodes().constBegin();
- while (c != node->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private) {
- if (!(*c)->doc().legaleseText().isEmpty())
- legaleseTexts.insertMulti((*c)->doc().legaleseText(), *c);
- if ((*c)->isInnerNode())
- findAllLegaleseTexts(static_cast<const InnerNode *>(*c));
- }
- ++c;
- }
-}
-
-void HtmlGenerator::findAllNamespaces(const InnerNode *node)
-{
- NodeList::ConstIterator c = node->childNodes().constBegin();
- while (c != node->childNodes().constEnd()) {
- if ((*c)->access() != Node::Private) {
- if ((*c)->isInnerNode() && (*c)->url().isEmpty()) {
- findAllNamespaces(static_cast<const InnerNode *>(*c));
- if ((*c)->type() == Node::Namespace) {
- const NamespaceNode *nspace = static_cast<const NamespaceNode *>(*c);
- // Ensure that the namespace's name is not empty (the root
- // namespace has no name).
- if (!nspace->name().isEmpty()) {
- namespaceIndex.insert(nspace->name(), *c);
- QString moduleName = (*c)->moduleName();
- if (moduleName == "Qt3SupportLight") {
- moduleNamespaceMap[moduleName].insert((*c)->name(), *c);
- moduleName = "Qt3Support";
- }
- if (!moduleName.isEmpty())
- moduleNamespaceMap[moduleName].insert((*c)->name(), *c);
- }
- }
- }
- }
- ++c;
- }
-}
-
int HtmlGenerator::hOffset(const Node *node)
{
switch (node->type()) {
return false;
}
-const Node *HtmlGenerator::findNodeForTarget(const QString &target,
- const Node *relative,
- CodeMarker *marker,
- const Atom *atom)
-{
- const Node *node = 0;
-
- if (target.isEmpty()) {
- node = relative;
- }
- else if (target.endsWith(".html")) {
- node = tree_->root()->findChildNodeByNameAndType(target, Node::Document);
- }
- else if (marker) {
- node = marker->resolveTarget(target, tree_, relative);
- if (!node) {
- node = tree_->findDocNodeByTitle(target, relative);
- }
- if (!node && atom) {
- node = tree_->findUnambiguousTarget(target, *const_cast<Atom**>(&atom), relative);
- }
- }
-
- if (!node)
- relative->doc().location().warning(tr("Cannot link to '%1'").arg(target));
- return node;
-}
const QPair<QString,QString> HtmlGenerator::anchorForNode(const Node *node)
{
return anchorPair;
}
-QString HtmlGenerator::getLink(const Atom *atom,
- const Node *relative,
- CodeMarker *marker,
- const Node** node)
+QString HtmlGenerator::getLink(const Atom *atom, const Node *relative, const Node** node)
{
QString link;
*node = 0;
node, which must be a direct child of the tree
root.
*/
- *node = tree_->root()->findChildNodeByNameAndType(first, Node::Document);
+ *node = qdb_->treeRoot()->findChildNodeByNameAndType(first, Node::Document);
}
else {
- *node = marker->resolveTarget(first, tree_, relative);
+ *node = qdb_->resolveTarget(first, relative);
if (!*node) {
- *node = tree_->findDocNodeByTitle(first, relative);
+ *node = qdb_->findDocNodeByTitle(first, relative);
}
if (!*node) {
- *node = tree_->findUnambiguousTarget(first, targetAtom, relative);
+ *node = qdb_->findUnambiguousTarget(first, targetAtom, relative);
}
}
if (*node) {
if (dn->title().startsWith("Porting"))
porting = true;
}
- QString name = marker->plainFullName(relative);
+ QString name = relative->plainFullName();
if (!porting && !name.startsWith("Q3")) {
if (obsoleteLinks) {
relative->doc().location().warning(tr("Link to obsolete item '%1' in %2")
target.
*/
while (!path.isEmpty()) {
- targetAtom = tree_->findTarget(path.first(), *node);
+ targetAtom = qdb_->findTarget(path.first(), *node);
if (targetAtom == 0)
break;
path.removeFirst();
const QString &url,
const QString &title)
{
- tree_->generateIndex(outputDir() + QLatin1Char('/') + fileBase + ".index", url, title, this);
+ qdb_->generateIndex(outputDir() + QLatin1Char('/') + fileBase + ".index", url, title, this);
}
void HtmlGenerator::generateStatus(const Node *node, CodeMarker *marker)
<< "We strongly advise against "
<< "using it in new code. See ";
- const DocNode *docNode = tree_->findDocNodeByTitle("Porting To Qt 4");
+ const DocNode *docNode = qdb_->findDocNodeByTitle("Porting To Qt 4");
Atom *targetAtom = 0;
if (docNode && node->type() == Node::Class) {
QString oldName(node->name());
oldName.remove(QLatin1Char('3'));
- targetAtom = tree_->findTarget(oldName,
- docNode);
+ targetAtom = qdb_->findTarget(oldName, docNode);
}
if (targetAtom) {
}
#endif
-void HtmlGenerator::beginLink(const QString &link,
- const Node *node,
- const Node *relative,
- CodeMarker *marker)
+void HtmlGenerator::beginLink(const QString &link, const Node *node, const Node *relative)
{
- Q_UNUSED(marker)
- Q_UNUSED(relative)
-
- this->link = link;
- if (link.isEmpty()) {
+ link_ = link;
+ if (link_.isEmpty()) {
if (showBrokenLinks)
out() << "<i>";
}
else if (node == 0 ||
(relative != 0 && node->status() == relative->status())) {
- out() << "<a href=\"" << link << "\">";
+ out() << "<a href=\"" << link_ << "\">";
}
else {
switch (node->status()) {
case Node::Obsolete:
- out() << "<a href=\"" << link << "\" class=\"obsolete\">";
+ out() << "<a href=\"" << link_ << "\" class=\"obsolete\">";
break;
case Node::Compat:
- out() << "<a href=\"" << link << "\" class=\"compat\">";
+ out() << "<a href=\"" << link_ << "\" class=\"compat\">";
break;
default:
- out() << "<a href=\"" << link << "\">";
+ out() << "<a href=\"" << link_ << "\">";
}
}
- inLink = true;
+ inLink_ = true;
}
void HtmlGenerator::endLink()
{
- if (inLink) {
- if (link.isEmpty()) {
+ if (inLink_) {
+ if (link_.isEmpty()) {
if (showBrokenLinks)
out() << "</i>";
}
out() << "</a>";
}
}
- inLink = false;
+ inLink_ = false;
inObsoleteLink = false;
}
out() << "<td class=\"tblQmlPropNode\"><p>";
out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
- if (!qpn->isWritable(tree_))
+ if (!qpn->isWritable(qdb_))
out() << "<span class=\"qmlreadonly\">read-only</span>";
if (qpn->isDefault())
out() << "<span class=\"qmldefault\">default</span>";
out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
if (!qpn->isReadOnlySet()) {
if (qpn->declarativeCppNode())
- qpn->setReadOnly(!qpn->isWritable(tree_));
+ qpn->setReadOnly(!qpn->isWritable(qdb_));
}
if (qpn->isReadOnly())
out() << "<span class=\"qmlreadonly\">read-only</span>";
out() << "<td class=\"tblQmlPropNode\"><p>";
out() << "<a name=\"" + refForNode(q) + "\"></a>";
if (!qpn->isReadOnlySet())
- qpn->setReadOnly(!qpn->isWritable(tree_));
+ qpn->setReadOnly(!qpn->isWritable(qdb_));
if (qpn->isReadOnly())
out() << "<span class=\"qmlreadonly\">read-only</span>";
if (qpn->isDefault())
xmlWriter().writeStartElement("topicref");
xmlWriter().writeAttribute("navtitle",t->navtitle());
if (t->href().isEmpty()) {
- const DocNode* fn = tree_->findDocNodeByTitle(t->navtitle());
+ const DocNode* fn = qdb_->findDocNodeByTitle(t->navtitle());
if (fn)
xmlWriter().writeAttribute("href",fileName(fn));
}
virtual void initializeGenerator(const Config& config);
virtual void terminateGenerator();
virtual QString format();
- virtual void generateTree(Tree *tree);
+ virtual void generateTree();
void generateCollisionPages();
void generateManifestFiles();
static QString sinceTitle(int i) { return sinceTitles[i]; }
protected:
- virtual void startText(const Node *relative, CodeMarker *marker);
virtual int generateAtom(const Atom *atom,
const Node *relative,
CodeMarker *marker);
};
const QPair<QString,QString> anchorForNode(const Node *node);
- const Node *findNodeForTarget(const QString &target,
- const Node *relative,
- CodeMarker *marker,
- const Atom *atom = 0);
void generateBreadCrumbs(const QString& title,
const Node *node,
CodeMarker *marker);
QString generateLowStatusMemberFile(const InnerNode *inner,
CodeMarker *marker,
CodeMarker::Status status);
- void generateClassHierarchy(const Node *relative,
- CodeMarker *marker,
- const NodeMap &classMap);
+ void generateClassHierarchy(const Node *relative, const NodeMap &classMap);
void generateAnnotatedList(const Node *relative,
CodeMarker *marker,
const NodeMap &nodeMap,
bool allOdd = false);
void generateCompactList(const Node *relative,
- CodeMarker *marker,
const NodeMap &classMap,
bool includeAlphabet,
QString commonPrefix = QString());
- void generateFunctionIndex(const Node *relative, CodeMarker *marker);
+ void generateFunctionIndex(const Node *relative);
void generateLegaleseList(const Node *relative, CodeMarker *marker);
- void generateOverviewList(const Node *relative, CodeMarker *marker);
+ void generateOverviewList(const Node *relative);
void generateSectionList(const Section& section,
const Node *relative,
CodeMarker *marker,
CodeMarker::SynopsisStyle style,
bool alignNames = false,
const QString* prefix = 0);
- void generateSectionInheritedList(const Section& section,
- const Node *relative,
- CodeMarker *marker);
+ void generateSectionInheritedList(const Section& section, const Node *relative);
QString highlightedCode(const QString& markedCode,
- CodeMarker* marker,
const Node* relative,
bool alignNames = false,
const Node* self = 0);
- void generateFullName(const Node *apparentNode,
- const Node *relative,
- CodeMarker *marker,
- const Node *actualNode = 0);
+ void generateFullName(const Node *apparentNode, const Node *relative, const Node *actualNode = 0);
void generateDetailedMember(const Node *node,
const InnerNode *relative,
CodeMarker *marker);
- void generateLink(const Atom *atom,
- const Node *relative,
- CodeMarker *marker);
+ void generateLink(const Atom *atom, CodeMarker *marker);
void generateStatus(const Node *node, CodeMarker *marker);
QString registerRef(const QString& ref);
virtual QString fileBase(const Node *node) const;
QString fileName(const Node *node);
- void findAllClasses(const InnerNode *node);
- void findAllFunctions(const InnerNode *node);
- void findAllLegaleseTexts(const InnerNode *node);
- void findAllNamespaces(const InnerNode *node);
static int hOffset(const Node *node);
static bool isThreeColumnEnumValueTable(const Atom *atom);
- QString getLink(const Atom *atom,
- const Node *relative,
- CodeMarker *marker,
- const Node** node);
+ QString getLink(const Atom *atom, const Node *relative, const Node** node);
virtual void generateIndex(const QString &fileBase,
const QString &url,
const QString &title);
#ifdef GENERATE_MAC_REFS
void generateMacRef(const Node *node, CodeMarker *marker);
#endif
- void beginLink(const QString &link,
- const Node *node,
- const Node *relative,
- CodeMarker *marker);
+ void beginLink(const QString &link, const Node *node, const Node *relative);
void endLink();
void generateExtractionMark(const Node *node, ExtractionMarkType markType);
void reportOrphans(const InnerNode* parent);
QMap<QString, QString> refMap;
int codeIndent;
HelpProjectWriter *helpProjectWriter;
- bool inLink;
bool inObsoleteLink;
- bool inContents;
- bool inSectionHeading;
- bool inTableHeader;
- int numTableRows;
- bool threeColumnEnumValueTable;
- QString link;
- QStringList sectionNumber;
QRegExp funcLeftParen;
QString style;
QString headerScripts;
QStringList stylesheets;
QStringList customHeadElements;
bool obsoleteLinks;
- QMap<QString, NodeMap > moduleClassMap;
- QMap<QString, NodeMap > moduleNamespaceMap;
- NodeMap nonCompatClasses;
- NodeMap mainClasses;
- NodeMap compatClasses;
- NodeMap obsoleteClasses;
- NodeMap namespaceIndex;
- NodeMap serviceClasses;
- NodeMap qmlClasses;
- QMap<QString, NodeMap > funcIndex;
- QMap<Text, const Node *> legaleseTexts;
QStack<QXmlStreamWriter*> xmlWriterStack;
static int id;
public:
**
****************************************************************************/
-/*
- main.cpp
-*/
-
#include <qglobal.h>
#include <stdlib.h>
#include "codemarker.h"
#include "puredocparser.h"
#include "tokenizer.h"
#include "tree.h"
-
+#include "qdocdatabase.h"
#include "jscodemarker.h"
#include "qmlcodemarker.h"
#include "qmlcodeparser.h"
-
#include <qdatetime.h>
#include <qdebug.h>
-
#include "qtranslator.h"
#ifndef QT_BOOTSTRAPPED
# include "qcoreapplication.h"
static QStringList defines;
static QStringList dependModules;
static QStringList indexDirs;
-static QHash<QString, Tree *> trees;
/*!
Print the help message to \c stdout.
Location langLocation = config.lastLocation();
/*
- Initialize the tree where all the parsed sources will be stored.
- The tree gets built as the source files are parsed, and then the
- documentation output is generated by traversing the tree.
+ Initialize the qdoc database, where all the parsed source files
+ will be stored. The database includes a tree of nodes, which gets
+ built as the source files are parsed. The documentation output is
+ generated by traversing that tree.
*/
- Tree *tree = new Tree;
- tree->setVersion(config.getString(CONFIG_VERSION));
+ QDocDatabase* qdb = QDocDatabase::qdocDB();
+ qdb->setVersion(config.getString(CONFIG_VERSION));
/*
By default, the only output format is HTML.
<< "There will probably be errors for missing links.";
}
}
- tree->readIndexes(indexFiles);
+ qdb->readIndexes(indexFiles);
QSet<QString> excludedDirs;
QSet<QString> excludedFiles;
CodeParser *codeParser = CodeParser::parserForHeaderFile(h.key());
if (codeParser) {
++parsed;
- codeParser->parseHeaderFile(config.location(), h.key(), tree);
+ codeParser->parseHeaderFile(config.location(), h.key());
usedParsers.insert(codeParser);
}
++h;
}
foreach (CodeParser *codeParser, usedParsers)
- codeParser->doneParsingHeaderFiles(tree);
+ codeParser->doneParsingHeaderFiles();
usedParsers.clear();
/*
CodeParser *codeParser = CodeParser::parserForSourceFile(s.key());
if (codeParser) {
++parsed;
- codeParser->parseSourceFile(config.location(), s.key(), tree);
+ codeParser->parseSourceFile(config.location(), s.key());
usedParsers.insert(codeParser);
}
++s;
}
foreach (CodeParser *codeParser, usedParsers)
- codeParser->doneParsingSourceFiles(tree);
+ codeParser->doneParsingSourceFiles();
/*
Now the big tree has been built from all the header and
source files. Resolve all the class names, function names,
targets, URLs, links, and other stuff that needs resolving.
*/
- tree->resolveGroups();
- tree->resolveTargets(tree->root());
- tree->resolveCppToQmlLinks();
- tree->resolveQmlInheritance();
+ qdb->resolveIssues();
/*
The tree is built and all the stuff that needed resolving
Generator* generator = Generator::generatorForFormat(*of);
if (generator == 0)
outputFormatsLocation.fatal(tr("Unknown output format '%1'").arg(*of));
- generator->generateTree(tree);
+ generator->generateTree();
++of;
}
/*
Generate the XML tag file, if it was requested.
*/
- QString tagFile = config.getString(CONFIG_TAGFILE);
- if (!tagFile.isEmpty()) {
- tree->generateTagFile(tagFile);
- }
+ qdb->generateTagFile(config.getString(CONFIG_TAGFILE));
//Generator::writeOutFileNames();
- tree->setVersion(QString());
+ QDocDatabase::qdocDB()->setVersion(QString());
Generator::terminate();
CodeParser::terminate();
CodeMarker::terminate();
qDeleteAll(translators);
#endif
#ifdef DEBUG_SHUTDOWN_CRASH
- qDebug() << "main(): Delete tree";
+ qDebug() << "main(): Delete qdoc database";
#endif
- delete tree;
+ QDocDatabase::destroyQdocDB();
#ifdef DEBUG_SHUTDOWN_CRASH
- qDebug() << "main(): Tree deleted";
+ qDebug() << "main(): qdoc database deleted";
#endif
}
processQdocconfFile(qf);
}
- qDeleteAll(trees);
return EXIT_SUCCESS;
}
#include "codemarker.h"
#include "codeparser.h"
#include <QUuid>
+#include "qdocdatabase.h"
#include <qdebug.h>
QT_BEGIN_NAMESPACE
}
/*!
+ Returns this node's name member. Appends "()" to the returned
+ name, if this node is a function node.
+ */
+QString Node::plainName() const
+{
+ if (type() == Node::Function)
+ return name_ + QLatin1String("()");
+ return name_;
+}
+
+/*!
+ Constructs and returns the node's fully qualified name by
+ recursively ascending the parent links and prepending each
+ parent name + "::". Breaks out when the parent pointer is
+ \a relative. Almost all calls to this function pass 0 for
+ \a relative.
+ */
+QString Node::plainFullName(const Node* relative) const
+{
+ if (name_.isEmpty())
+ return QLatin1String("global");
+
+ QString fullName;
+ const Node* node = this;
+ while (node) {
+ fullName.prepend(node->plainName());
+ if (node->parent() == relative || node->parent()->subType() == Node::Collision ||
+ node->parent()->name().isEmpty())
+ break;
+ fullName.prepend(QLatin1String("::"));
+ node = node->parent();
+ }
+ return fullName;
+}
+
+/*!
+ Constructs and returns this node's full name. The \a relative
+ node is either null or is a collision node.
+ */
+QString Node::fullName(const Node* relative) const
+{
+ if (type() == Node::Document) {
+ const DocNode* dn = static_cast<const DocNode*>(this);
+ // Only print modulename::type on collision pages.
+ if (!dn->qmlModuleIdentifier().isEmpty() && relative != 0 && relative->isCollisionNode())
+ return dn->qmlModuleIdentifier() + "::" + dn->title();
+ return dn->title();
+ }
+ else if (type() == Node::Class) {
+ const ClassNode* cn = static_cast<const ClassNode*>(this);
+ if (!cn->serviceName().isEmpty())
+ return cn->serviceName();
+ }
+ return plainFullName(relative);
+}
+
+/*!
Sets this Node's Doc to \a doc. If \a replace is false and
this Node already has a Doc, a warning is reported that the
Doc is being overridden, and it reports where the previous
QPair<QString,QString> linkPair;
linkPair.first = link;
linkPair.second = desc;
- linkMap[linkType] = linkPair;
+ linkMap_[linkType] = linkPair;
}
/*!
}
/*!
+ Returns true if this node's members coolection is not empty.
+ */
+bool InnerNode::hasMembers() const
+{
+ return !members_.isEmpty();
+}
+
+/*!
+ Returns true if this node's members collection contains at
+ least one namespace node.
+ */
+bool InnerNode::hasNamespaces() const
+{
+ if (!members_.isEmpty()) {
+ NodeList::const_iterator i = members_.begin();
+ while (i != members_.end()) {
+ if ((*i)->isNamespace())
+ return true;
+ ++i;
+ }
+ }
+ return false;
+}
+
+/*!
+ Returns true if this node's members collection contains at
+ least one class node.
+ */
+bool InnerNode::hasClasses() const
+{
+ if (!members_.isEmpty()) {
+ NodeList::const_iterator i = members_.begin();
+ while (i != members_.end()) {
+ if ((*i)->isClass())
+ return true;
+ ++i;
+ }
+ }
+ return false;
+}
+
+/*!
+ Loads \a out with all this node's member nodes that are namespace nodes.
+ */
+void InnerNode::getMemberNamespaces(NodeMap& out)
+{
+ out.clear();
+ NodeList::const_iterator i = members_.begin();
+ while (i != members_.end()) {
+ if ((*i)->isNamespace())
+ out.insert((*i)->name(),(*i));
+ ++i;
+ }
+}
+
+/*!
+ Loads \a out with all this node's member nodes that are class nodes.
+ */
+void InnerNode::getMemberClasses(NodeMap& out)
+{
+ out.clear();
+ NodeList::const_iterator i = members_.begin();
+ while (i != members_.end()) {
+ if ((*i)->isClass())
+ out.insert((*i)->name(),(*i));
+ ++i;
+ }
+}
+
+/*!
Find the node in this node's children that has the
given \a name. If this node is a QML class node, be
sure to also look in the children of its property
if (node && node->subType() != QmlPropertyGroup)
return node;
if ((type() == Document) && (subType() == QmlClass)) {
- for (int i=0; i<children.size(); ++i) {
- Node* n = children.at(i);
+ for (int i=0; i<children_.size(); ++i) {
+ Node* n = children_.at(i);
if (n->subType() == QmlPropertyGroup) {
node = static_cast<InnerNode*>(n)->findChildNodeByName(name);
if (node)
*/
if (nodes.isEmpty()) {
if ((type() == Document) && (subType() == QmlClass)) {
- for (int i=0; i<children.size(); ++i) {
- node = children.at(i);
+ for (int i=0; i<children_.size(); ++i) {
+ node = children_.at(i);
if (node->subType() == QmlPropertyGroup) {
node = static_cast<InnerNode*>(node)->findChildNodeByName(name);
if (node) {
}
}
if (qml && (type() == Document) && (subType() == QmlClass)) {
- for (int i=0; i<children.size(); ++i) {
- Node* node = children.at(i);
+ for (int i=0; i<children_.size(); ++i) {
+ Node* node = children_.at(i);
if (node->subType() == QmlPropertyGroup) {
node = static_cast<InnerNode*>(node)->findChildNodeByName(name);
if (node)
*/
void InnerNode::deleteChildren()
{
- NodeList childrenCopy = children; // `children` will be changed in ~Node()
+ NodeList childrenCopy = children_; // `children_` will be changed in ~Node()
qDeleteAll(childrenCopy);
}
*/
const EnumNode *InnerNode::findEnumNodeForValue(const QString &enumValue) const
{
- foreach (const Node *node, enumChildren) {
+ foreach (const Node *node, enumChildren_) {
const EnumNode *enume = static_cast<const EnumNode *>(node);
if (enume->hasItem(enumValue))
return enume;
*/
void InnerNode::addInclude(const QString& include)
{
- inc.append(include);
+ includes_.append(include);
}
/*!
*/
void InnerNode::setIncludes(const QStringList& includes)
{
- inc = includes;
+ includes_ = includes;
}
/*!
*/
void InnerNode::addChild(Node *child)
{
- children.append(child);
+ children_.append(child);
if ((child->type() == Function) || (child->type() == QmlMethod)) {
FunctionNode *func = (FunctionNode *) child;
if (!primaryFunctionMap.contains(func->name())) {
}
else {
if (child->type() == Enum)
- enumChildren.append(child);
+ enumChildren_.append(child);
childMap.insertMulti(child->name(), child);
}
}
*/
void InnerNode::removeChild(Node *child)
{
- children.removeAll(child);
- enumChildren.removeAll(child);
+ children_.removeAll(child);
+ enumChildren_.removeAll(child);
if (child->type() == Function) {
QMap<QString, Node *>::Iterator prim =
primaryFunctionMap.find(child->name());
*/
QString Node::moduleName() const
{
- if (!mod.isEmpty())
- return mod;
+ if (!moduleName_.isEmpty())
+ return moduleName_;
QString path = location().filePath();
QString pattern = QString("src") + QDir::separator();
return result;
}
-QMap<QString, DocNode*> DocNode::qmlModuleMap_;
-
/*!
\class DocNode
*/
}
/*!
- The QML module map contains an entry for each QML module
- identifier. A QML module identifier is constucted from the
- QML module name and the module's major version number, like
- this: \e {<module-name><major-version>}
-
- If the QML module map does not contain the module identifier
- \a qmid, insert the QML module node \a fn mapped to \a qmid.
- */
-void DocNode::insertQmlModuleNode(const QString& qmid, DocNode* fn)
-{
- if (!qmlModuleMap_.contains(qmid))
- qmlModuleMap_.insert(qmid,fn);
-}
-
-/*!
- Returns a pointer to the QML module node (DocNode) that is
- mapped to the QML module identifier constructed from \a arg.
- If that QML module node does not yet exist, it is constructed
- and inserted into the QML module map mapped to the QML module
- identifier constructed from \a arg.
- */
-DocNode* DocNode::lookupQmlModuleNode(Tree* tree, const ArgLocPair& arg)
-{
- QStringList dotSplit;
- QStringList blankSplit = arg.first.split(QLatin1Char(' '));
- QString qmid = blankSplit[0];
- if (blankSplit.size() > 1) {
- dotSplit = blankSplit[1].split(QLatin1Char('.'));
- qmid += dotSplit[0];
- }
- DocNode* fn = 0;
- if (qmlModuleMap_.contains(qmid))
- fn = qmlModuleMap_.value(qmid);
- if (!fn) {
- fn = new DocNode(tree->root(), arg.first, Node::QmlModule, Node::OverviewPage);
- fn->setQmlModule(arg);
- insertQmlModuleNode(qmid,fn);
- }
- return fn;
-}
-
-/*!
Returns true if this QML type or property group contains a
property named \a name.
*/
bool QmlClassNode::qmlOnly = false;
QMultiMap<QString,Node*> QmlClassNode::inheritedBy;
-QMap<QString, QmlClassNode*> QmlClassNode::qmlModuleMemberMap_;
/*!
Constructs a Qml class node (i.e. a Document node with the
void QmlClassNode::terminate()
{
inheritedBy.clear();
- qmlModuleMemberMap_.clear();
}
/*!
- Insert the QML type node \a qcn into the static QML module
- member map. The key is \a qmid + "::" + qcn->name().
- */
-void QmlClassNode::insertQmlModuleMember(const QString& qmid, QmlClassNode* qcn)
-{
- qmlModuleMemberMap_.insert(qmid + "::" + qcn->name(), qcn);
-}
-
-/*!
- Lookup the QML type node identified by the Qml module id
- \a qmid and QML type \a name, and return a pointer to the
- node. The key is \a qmid + "::" + qcn->name().
- */
-QmlClassNode* QmlClassNode::lookupQmlTypeNode(const QString& qmid, const QString& name)
-{
- return qmlModuleMemberMap_.value(qmid + "::" + name);
-}
-
-#if 0
-/*!
- The base file name for this kind of node has "qml_"
- prepended to it.
-
- But not yet. Still testing.
- */
-QString QmlClassNode::fileBase() const
-{
- return Node::fileBase();
-}
-#endif
-/*!
Record the fact that QML class \a base is inherited by
QML class \a sub.
*/
is returned is the concatenation of the QML module name
and its version number. e.g., if an element or component
is defined to be in the QML module QtQuick 1, its module
- identifier is "QtQuick1". See setQmlModule().
+ identifier is "QtQuick1". See setQmlModuleInfo().
*/
/*!
true is returned. If any of the three is not found or is not
correct, false is returned.
*/
-bool Node::setQmlModule(const ArgLocPair& arg)
+bool Node::setQmlModuleInfo(const QString& arg)
{
QStringList dotSplit;
- QStringList blankSplit = arg.first.split(QLatin1Char(' '));
+ QStringList blankSplit = arg.split(QLatin1Char(' '));
qmlModuleName_ = blankSplit[0];
qmlModuleVersionMajor_ = "1";
qmlModuleVersionMinor_ = "0";
}
/*!
- Most QML elements don't have an \\inherits command in their
- \\qmlclass command. This leaves qdoc bereft, when it tries
- to output the line in the documentation that specifies the
- QML element that a QML element inherits.
- */
-void QmlClassNode::resolveInheritance(Tree* tree)
-{
- if (!links().empty() && links().contains(Node::InheritsLink)) {
- QPair<QString,QString> linkPair;
- linkPair = links()[Node::InheritsLink];
- QStringList strList = linkPair.first.split("::");
- Node* n = tree->findQmlClassNode(strList);
- if (n) {
- base_ = static_cast<DocNode*>(n);
- if (base_ && base_->subType() == Node::QmlClass) {
- return;
- }
- }
- if (base_ && base_->subType() == Node::Collision) {
- const NameCollisionNode* ncn = static_cast<const NameCollisionNode*>(base_);
- const NodeList& children = ncn->childNodes();
- for (int i=0; i<importList_.size(); ++i) {
- QString qmid = importList_.at(i).first + importList_.at(i).second;
- for (int j=0; j<children.size(); ++j) {
- if (qmid == children.at(j)->qmlModuleIdentifier()) {
- base_ = static_cast<DocNode*>(children.at(j));
- return;
- }
- }
- }
- QString qmid = qmlModuleIdentifier();
- for (int k=0; k<children.size(); ++k) {
- if (qmid == children.at(k)->qmlModuleIdentifier()) {
- base_ = static_cast<QmlClassNode*>(children.at(k));
- return;
- }
- }
- }
- if (base_)
- return;
- }
- if (cnode_) {
- QmlClassNode* qcn = cnode_->findQmlBaseNode();
- if (qcn != 0)
- base_ = qcn;
- }
- return;
-}
-
-/*!
Constructs a Qml basic type node (i.e. a Document node with
the subtype QmlBasicType. The new node has the given
\a parent and \a name.
...because the tokenizer gets confused on \e{explicit}.
*/
-bool QmlPropertyNode::isWritable(Tree* tree)
+bool QmlPropertyNode::isWritable(QDocDatabase* qdb)
{
if (readOnly_ != FlagValueDefault)
return !fromFlagValue(readOnly_, false);
if (qcn) {
if (qcn->cppClassRequired()) {
if (qcn->classNode()) {
- PropertyNode* pn = correspondingProperty(tree);
+ PropertyNode* pn = correspondingProperty(qdb);
if (pn)
return pn->isWritable();
else
Returns a pointer this QML property's corresponding C++
property, if it has one.
*/
-PropertyNode* QmlPropertyNode::correspondingProperty(Tree *tree)
+PropertyNode* QmlPropertyNode::correspondingProperty(QDocDatabase* qdb)
{
PropertyNode* pn;
// the property group, <group>.<property>.
QStringList path(extractClassName(pn->qualifiedDataType()));
- Node* nn = tree->findClassNode(path);
+ Node* nn = qdb->findClassNode(path);
if (nn) {
ClassNode* cn = static_cast<ClassNode*>(nn);
PropertyNode *pn2 = cn->findPropertyNode(dotSplit[1]);
if (child->parent())
child->parent()->removeChild(child);
child->setParent((InnerNode*)this);
- children.append(child);
+ children_.append(child);
}
}
return str;
}
+/*!
+ Prints the inner node's list of children.
+ For debugging only.
+ */
+void InnerNode::printChildren(const QString& title)
+{
+ qDebug() << title << name() << children_.size();
+ if (children_.size() > 0) {
+ for (int i=0; i<children_.size(); ++i) {
+ Node* n = children_.at(i);
+ qDebug() << " CHILD:" << n->name() << n->nodeTypeString() << n->nodeSubtypeString();
+ }
+ }
+}
+
+/*!
+ Prints the inner node's list of members.
+ For debugging only.
+ */
+void InnerNode::printMembers(const QString& title)
+{
+ qDebug() << title << name() << members_.size();
+ if (members_.size() > 0) {
+ for (int i=0; i<members_.size(); ++i) {
+ Node* n = members_.at(i);
+ qDebug() << " MEMBER:" << n->name() << n->nodeTypeString() << n->nodeSubtypeString();
+ }
+ }
+}
+
QT_END_NAMESPACE
**
****************************************************************************/
-/*
- node.h
-*/
-
#ifndef NODE_H
#define NODE_H
class Node;
class ClassNode;
class InnerNode;
-class ClassNode;
class ExampleNode;
class QmlClassNode;
-class Tree;
+class QDocDatabase;
+typedef QList<Node*> NodeList;
typedef QMap<QString, const Node*> NodeMap;
typedef QMultiMap<QString, Node*> NodeMultiMap;
typedef QMultiMap<QString, const ExampleNode*> ExampleNodeMap;
virtual ~Node();
+ QString plainName() const;
+ QString plainFullName(const Node* relative = 0) const;
+ QString fullName(const Node* relative=0) const;
+
void setAccess(Access access) { access_ = access; }
void setLocation(const Location& location) { loc = location; }
void setDoc(const Doc& doc, bool replace = false);
void setThreadSafeness(ThreadSafeness safeness) { safeness_ = safeness; }
void setSince(const QString &since);
void setRelates(InnerNode* pseudoParent);
- void setModuleName(const QString &module) { mod = module; }
+ void setModuleName(const QString &name) { moduleName_ = name; }
void setLink(LinkType linkType, const QString &link, const QString &desc);
void setUrl(const QString &url);
void setTemplateStuff(const QString &templateStuff) { templateStuff_ = templateStuff; }
virtual bool isLeaf() const { return false; }
virtual bool isReimp() const { return false; }
virtual bool isFunction() const { return false; }
+ virtual bool isNamespace() const { return false; }
+ virtual bool isClass() const { return false; }
virtual bool isQmlNode() const { return false; }
virtual bool isQtQuickNode() const { return false; }
virtual bool isAbstract() const { return false; }
virtual bool isQmlPropertyGroup() const { return false; }
virtual bool isCollisionNode() const { return false; }
virtual bool isAttached() const { return false; }
+ virtual bool hasMembers() const { return false; }
+ virtual bool hasNamespaces() const { return false; }
+ virtual bool hasClasses() const { return false; }
virtual void setAbstract(bool ) { }
virtual QString title() const { return QString(); }
virtual bool hasProperty(const QString& ) const { return false; }
+ virtual void getMemberNamespaces(NodeMap& ) { }
+ virtual void getMemberClasses(NodeMap& ) { }
bool isInternal() const;
bool isIndexNode() const { return indexNodeFlag_; }
Type type() const { return nodeType_; }
InnerNode* parent() const { return parent_; }
InnerNode* relates() const { return relatesTo_; }
const QString& name() const { return name_; }
- QMap<LinkType, QPair<QString,QString> > links() const { return linkMap; }
+ const QMap<LinkType, QPair<QString,QString> >& links() const { return linkMap_; }
QString moduleName() const;
QString url() const;
virtual QString nameForLists() const { return name_; }
virtual QString outputFileName() const { return QString(); }
- virtual void addGroupMember(Node* ) { }
- virtual void addQmlModuleMember(Node* ) { }
Access access() const { return access_; }
QString accessString() const;
virtual QString qmlModuleName() const { return qmlModuleName_; }
virtual QString qmlModuleVersion() const { return qmlModuleVersionMajor_ + "." + qmlModuleVersionMinor_; }
virtual QString qmlModuleIdentifier() const { return qmlModuleName_ + qmlModuleVersionMajor_; }
- virtual bool setQmlModule(const ArgLocPair& );
+ virtual bool setQmlModuleInfo(const QString& );
virtual ClassNode* classNode() { return 0; }
virtual void setClassNode(ClassNode* ) { }
virtual void clearCurrentChild() { }
- virtual const ImportList* importList() const { return 0; }
- virtual void setImportList(const ImportList& ) { }
virtual const Node* applyModuleIdentifier(const Node* ) const { return 0; }
virtual QString idNumber() { return "0"; }
QmlClassNode* qmlClassNode();
QString name_;
Location loc;
Doc d;
- QMap<LinkType, QPair<QString, QString> > linkMap;
- QString mod;
+ QMap<LinkType, QPair<QString, QString> > linkMap_;
+ QString moduleName_;
QString url_;
QString sinc;
QString templateStuff_;
class EnumNode;
class NameCollisionNode;
-typedef QList<Node*> NodeList;
-typedef QMap<QString, const Node*> NodeMap;
-typedef QMultiMap<QString, Node*> NodeMultiMap;
-
class InnerNode : public Node
{
public:
const FunctionNode* findFunctionNode(const QString& name) const;
const FunctionNode* findFunctionNode(const FunctionNode* clone) const;
const EnumNode* findEnumNodeForValue(const QString &enumValue) const;
- const NodeList & childNodes() const { return children; }
+ const NodeList & childNodes() const { return children_; }
const NodeList & relatedNodes() const { return related_; }
- int count() const { return children.size(); }
+
+ void addMember(Node* node) { members_.append(node); }
+ const NodeList& members() const { return members_; }
+ virtual bool hasMembers() const;
+ virtual bool hasNamespaces() const;
+ virtual bool hasClasses() const;
+ virtual void getMemberNamespaces(NodeMap& out);
+ virtual void getMemberClasses(NodeMap& out);
+
+ int count() const { return children_.size(); }
int overloadNumber(const FunctionNode* func) const;
NodeList overloads(const QString &funcName) const;
- const QStringList& includes() const { return inc; }
+ const QStringList& includes() const { return includes_; }
QStringList primaryKeys();
QStringList secondaryKeys();
virtual void setOutputFileName(const QString& f) { outputFileName_ = f; }
virtual QString outputFileName() const { return outputFileName_; }
+ void printChildren(const QString& title);
+ void printMembers(const QString& title);
+
protected:
InnerNode(Type type, InnerNode* parent, const QString& name);
QString outputFileName_;
QStringList pageKeywds;
- QStringList inc;
- NodeList children;
- NodeList enumChildren;
+ QStringList includes_;
+ NodeList children_;
+ NodeList members_;
+ NodeList enumChildren_;
NodeList related_;
QMap<QString, Node*> childMap;
QMap<QString, Node*> primaryFunctionMap;
public:
NamespaceNode(InnerNode* parent, const QString& name);
virtual ~NamespaceNode() { }
+ virtual bool isNamespace() const { return true; }
};
class ClassNode;
public:
ClassNode(InnerNode* parent, const QString& name);
virtual ~ClassNode() { }
+ virtual bool isClass() const { return true; }
void addBaseClass(Access access,
ClassNode* node,
void setTitle(const QString &title) { title_ = title; }
void setSubTitle(const QString &subTitle) { subtitle_ = subTitle; }
- virtual void addGroupMember(Node* node) { nodeList.append(node); }
- virtual void addQmlModuleMember(Node* node) { nodeList.append(node); }
SubType subType() const { return nodeSubtype_; }
virtual QString title() const;
virtual QString fullTitle() const;
virtual QString subTitle() const;
virtual QString imageFileName() const { return QString(); }
- const NodeList& groupMembers() const { return nodeList; }
- const NodeList& qmlModuleMembers() const { return nodeList; }
virtual QString nameForLists() const { return title(); }
virtual void setImageFileName(const QString& ) { }
virtual bool isQmlPropertyGroup() const { return (nodeSubtype_ == QmlPropertyGroup); }
virtual bool hasProperty(const QString& ) const;
- static void insertQmlModuleNode(const QString& qmid, DocNode* fn);
- static DocNode* lookupQmlModuleNode(Tree* tree, const ArgLocPair& arg);
-
protected:
SubType nodeSubtype_;
QString title_;
QString subtitle_;
- NodeList nodeList; // used for groups and QML modules.
-
- static QMap<QString, DocNode*> qmlModuleMap_;
};
class NameCollisionNode : public DocNode
virtual void setClassNode(ClassNode* cn) { cnode_ = cn; }
virtual void setCurrentChild();
virtual void clearCurrentChild();
- virtual const ImportList* importList() const { return &importList_; }
- virtual void setImportList(const ImportList& il) { importList_ = il; }
virtual bool isAbstract() const { return abstract_; }
virtual void setAbstract(bool b) { abstract_ = b; }
+ const ImportList& importList() const { return importList_; }
+ void setImportList(const ImportList& il) { importList_ = il; }
const DocNode* qmlBase() const { return base_; }
- void resolveInheritance(Tree* tree);
+ void setQmlBase(DocNode* b) { base_ = b; }
void requireCppClass() { cnodeRequired_ = true; }
bool cppClassRequired() const { return cnodeRequired_; }
static void addInheritedBy(const QString& base, Node* sub);
static void subclasses(const QString& base, NodeList& subs);
static void terminate();
- static void insertQmlModuleMember(const QString& qmid, QmlClassNode* qcn);
- static QmlClassNode* lookupQmlTypeNode(const QString& qmid, const QString& name);
-
public:
static bool qmlOnly;
static QMultiMap<QString,Node*> inheritedBy;
- static QMap<QString, QmlClassNode*> qmlModuleMemberMap_;
private:
bool abstract_;
bool isDefault() const { return isdefault_; }
bool isStored() const { return fromFlagValue(stored_,true); }
bool isDesignable() const { return fromFlagValue(designable_,false); }
- bool isWritable(Tree* tree);
+ bool isWritable(QDocDatabase* qdb);
bool isReadOnly() const { return fromFlagValue(readOnly_,false); }
virtual bool isAttached() const { return attached_; }
virtual bool isQmlNode() const { return true; }
virtual QString qmlModuleIdentifier() const { return parent()->qmlModuleIdentifier(); }
virtual bool hasProperty(const QString& name) const;
- PropertyNode* correspondingProperty(Tree* tree);
+ PropertyNode* correspondingProperty(QDocDatabase* qdb);
const QString& element() const { return static_cast<QmlPropGroupNode*>(parent())->element(); }
void appendQmlPropNode(QmlPropertyNode* p) { qmlPropNodes_.append(p); }
return Atom::Code;
}
-QString PlainCodeMarker::plainName( const Node * /* node */ )
-{
- return QString();
-}
-
-QString PlainCodeMarker::plainFullName(const Node * /* node */, const Node * /* relative */)
-{
- return QString();
-}
-
QString PlainCodeMarker::markedUpCode( const QString& code,
const Node * /* relative */,
const Location & /* location */ )
bool recognizeExtension( const QString& ext );
bool recognizeLanguage( const QString& lang );
Atom::Type atomType() const;
- QString plainName( const Node *node );
- QString plainFullName( const Node *node, const Node *relative );
QString markedUpCode( const QString& code, const Node *relative, const Location &location );
QString markedUpSynopsis( const Node *node, const Node *relative,
SynopsisStyle style );
#include "codechunk.h"
#include "config.h"
#include "tokenizer.h"
-#include "tree.h"
#include <qdebug.h>
+#include "qdocdatabase.h"
#include "puredocparser.h"
QT_BEGIN_NAMESPACE
+/*!
+ Constructs the pure doc parser.
+*/
PureDocParser::PureDocParser()
{
}
+/*!
+ Destroys the pure doc parser.
+ */
PureDocParser::~PureDocParser()
{
}
+/*!
+ Returns a list of the kinds of files that the pure doc
+ parser is meant to parse. The elements of the list are
+ file suffixes.
+ */
QStringList PureDocParser::sourceFileNameFilter()
{
return QStringList() << "*.qdoc" << "*.qtx" << "*.qtt" << "*.js";
}
/*!
- Parse the source file identified by \a filePath and add its
- parsed contents to the big \a tree. \a location is used for
+ Parses the source file identified by \a filePath and adds its
+ parsed contents to the database. The \a location is used for
reporting errors.
*/
-void PureDocParser::parseSourceFile(const Location& location,
- const QString& filePath,
- Tree *tree)
+void PureDocParser::parseSourceFile(const Location& location, const QString& filePath)
{
QFile in(filePath);
currentFile_ = filePath;
}
createOutputSubdirectory(location, filePath);
- reset(tree);
+ reset();
Location fileLocation(filePath);
Tokenizer fileTokenizer(fileLocation, in);
tokenizer = &fileTokenizer;
}
}
+ Node* treeRoot = QDocDatabase::qdocDB()->treeRoot();
NodeList::Iterator n = nodes.begin();
QList<Doc>::Iterator d = docs.begin();
while (n != nodes.end()) {
(*n)->setDoc(*d);
if ((*n)->isInnerNode() && ((InnerNode *)*n)->includes().isEmpty()) {
InnerNode *m = static_cast<InnerNode *>(*n);
- while (m->parent() != tree_->root())
+ while (m->parent() && m->parent() != treeRoot)
m = m->parent();
if (m == *n)
((InnerNode *)*n)->addInclude((*n)->name());
virtual ~PureDocParser();
virtual QStringList sourceFileNameFilter();
- virtual void parseSourceFile(const Location& location, const QString& filePath, Tree* tree);
+ virtual void parseSourceFile(const Location& location, const QString& filePath);
private:
bool processQdocComments();
openedlist.h \
plaincodemarker.h \
puredocparser.h \
+ qdocdatabase.h \
quoter.h \
separator.h \
text.h \
openedlist.cpp \
plaincodemarker.cpp \
puredocparser.cpp \
+ qdocdatabase.cpp \
quoter.cpp \
separator.cpp \
text.cpp \
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tree.h"
+#include "qdocdatabase.h"
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+static NodeMap emptyNodeMap_;
+static NodeMultiMap emptyNodeMultiMap_;
+
+/*! \class QDocDatabase
+ */
+
+QDocDatabase* QDocDatabase::qdocDB_ = NULL;
+
+/*!
+ Constructs the singleton qdoc database object.
+ It constructs a singleton Tree object with this
+ qdoc database pointer.
+ */
+QDocDatabase::QDocDatabase()
+{
+ tree_ = new Tree(this);
+}
+
+/*!
+ Destroys the qdoc database object. This requires deleting
+ the tree of nodes, which deletes each node.
+ */
+QDocDatabase::~QDocDatabase()
+{
+ masterMap_.clear();
+ delete tree_;
+}
+
+/*! \fn Tree* QDocDatabase::tree()
+ Returns the pointer to the tree. This function is for compatibility
+ with the current qdoc. It will be removed when the QDocDatabase class
+ replaces the current structures.
+ */
+
+/*!
+ Creates the singleton. Allows only one instance of the class
+ to be created. Returns a pointer to the singleton.
+*/
+QDocDatabase* QDocDatabase::qdocDB()
+{
+ if (!qdocDB_)
+ qdocDB_ = new QDocDatabase;
+ return qdocDB_;
+}
+
+/*!
+ Destroys the singleton.
+ */
+void QDocDatabase::destroyQdocDB()
+{
+ if (qdocDB_) {
+ delete qdocDB_;
+ qdocDB_ = 0;
+ }
+}
+
+/*!
+ \fn const DocNodeMap& QDocDatabase::modules() const
+ Returns a const reference to the collection of all
+ module nodes.
+*/
+
+/*!
+ \fn const DocNodeMap& QDocDatabase::qmlModules() const
+ Returns a const reference to the collection of all
+ QML module nodes.
+*/
+
+/*!
+ Looks up the module node named \a name in the collection
+ of all module nodes. If a match is found, a pointer to the
+ node is returned. Otherwise, a new module node named \a name
+ is created and inserted into the collection, and the pointer
+ to that node is returned.
+ */
+DocNode* QDocDatabase::addModule(const QString& name)
+{
+ return findModule(name,true);
+}
+
+/*!
+ Looks up the QML module node named \a name in the collection
+ of all QML module nodes. If a match is found, a pointer to the
+ node is returned. Otherwise, a new QML module node named \a name
+ is created and inserted into the collection, and the pointer
+ to that node is returned.
+ */
+DocNode* QDocDatabase::addQmlModule(const QString& name)
+{
+ return findQmlModule(name,true);
+}
+
+/*!
+ Looks up the C++ module named \a moduleName. If it isn't
+ there, create it. Then append \a node to the module's child
+ list. The parent of \a node is not changed by this function.
+ Returns the module node.
+ */
+DocNode* QDocDatabase::addToModule(const QString& moduleName, Node* node)
+{
+ DocNode* dn = findModule(moduleName,true);
+ dn->addMember(node);
+ node->setModuleName(moduleName);
+ return dn;
+}
+
+/*!
+ Looks up the QML module named \a qmlModuleName. If it isn't
+ there, create it. Then append \a node to the module's child
+ list. The parent of \a node is not changed by this function.
+ Returns a pointer to the QML module node.
+ */
+DocNode* QDocDatabase::addToQmlModule(const QString& qmlModuleName, Node* node)
+{
+ DocNode* dn = findQmlModule(qmlModuleName,true);
+ dn->addMember(node);
+ node->setQmlModuleInfo(qmlModuleName);
+ if (node->subType() == Node::QmlClass) {
+ QString t = node->qmlModuleIdentifier() + "::" + node->name();
+ QmlClassNode* n = static_cast<QmlClassNode*>(node);
+ if (!qmlTypeMap_.contains(t))
+ qmlTypeMap_.insert(t,n);
+ if (!masterMap_.contains(t))
+ masterMap_.insert(t,node);
+ if (!masterMap_.contains(node->name(),node))
+ masterMap_.insert(node->name(),node);
+ }
+ return dn;
+}
+
+/*!
+ Find the module node named \a name and return a pointer
+ to it. If a matching node is not found and \a addIfNotFound
+ is true, add a new module node named \a name and return
+ a pointer to that one. Otherwise, return 0.
+
+ If a new module node is added, its parent is the tree root,
+ but the new module node is not added to the child list of the
+ tree root.
+ */
+DocNode* QDocDatabase::findModule(const QString& name, bool addIfNotFound)
+{
+ DocNodeMap::const_iterator i = modules_.find(name);
+ if (i != modules_.end()) {
+ return i.value();
+ }
+ if (addIfNotFound) {
+ DocNode* dn = new DocNode(tree_->root(), name, Node::Module, Node::OverviewPage);
+ modules_.insert(name,dn);
+ if (!masterMap_.contains(name,dn))
+ masterMap_.insert(name,dn);
+ return dn;
+ }
+ return 0;
+}
+
+/*!
+ Find the QML module node named \a name and return a pointer
+ to it. If a matching node is not found and \a addIfNotFound
+ is true, add a new QML module node named \a name and return
+ a pointer to that one. Otherwise, return 0.
+
+ If a new QML module node is added, its parent is the tree root,
+ but the new QML module node is not added to the child list of
+ the tree root.
+ */
+DocNode* QDocDatabase::findQmlModule(const QString& name, bool addIfNotFound)
+{
+ QStringList dotSplit;
+ QStringList blankSplit = name.split(QLatin1Char(' '));
+ QString qmid = blankSplit[0];
+ if (blankSplit.size() > 1) {
+ dotSplit = blankSplit[1].split(QLatin1Char('.'));
+ qmid += dotSplit[0];
+ }
+ DocNode* dn = 0;
+ if (qmlModules_.contains(qmid))
+ dn = qmlModules_.value(qmid);
+ else if (addIfNotFound) {
+ dn = new DocNode(tree_->root(), name, Node::QmlModule, Node::OverviewPage);
+ dn->setQmlModuleInfo(name);
+ qmlModules_.insert(qmid,dn);
+ masterMap_.insert(qmid,dn);
+ masterMap_.insert(dn->name(),dn);
+ }
+ return dn;
+}
+
+/*!
+ Looks up the QML type node identified by the Qml module id
+ \a qmid and QML type \a name and returns a pointer to the
+ QML type node. The key is \a qmid + "::" + \a name.
+
+ If the QML module id is empty, it looks up the QML type by
+ \a name only.
+ */
+QmlClassNode* QDocDatabase::findQmlType(const QString& qmid, const QString& name) const
+{
+ if (!qmid.isEmpty())
+ return qmlTypeMap_.value(qmid + "::" + name);
+
+ QStringList path(name);
+ Node* n = tree_->findNodeByNameAndType(path, Node::Document, Node::QmlClass, 0, true);
+ if (n) {
+ if (n->subType() == Node::QmlClass)
+ return static_cast<QmlClassNode*>(n);
+ else if (n->subType() == Node::Collision) {
+ NameCollisionNode* ncn;
+ ncn = static_cast<NameCollisionNode*>(n);
+ return static_cast<QmlClassNode*>(ncn->findAny(Node::Document,Node::QmlClass));
+ }
+ }
+ return 0;
+
+}
+
+/*!
+ For debugging only.
+ */
+void QDocDatabase::printModules() const
+{
+ DocNodeMap::const_iterator i = modules_.begin();
+ while (i != modules_.end()) {
+ qDebug() << " " << i.key();
+ ++i;
+ }
+}
+
+/*!
+ For debugging only.
+ */
+void QDocDatabase::printQmlModules() const
+{
+ DocNodeMap::const_iterator i = qmlModules_.begin();
+ while (i != qmlModules_.end()) {
+ qDebug() << " " << i.key();
+ ++i;
+ }
+}
+
+/*!
+ Traverses the database to construct useful data structures
+ for use when outputting certain significant collections of
+ things, C++ classes, QML types, "since" lists, and other
+ stuff.
+ */
+void QDocDatabase::buildCollections()
+{
+ nonCompatClasses_.clear();
+ mainClasses_.clear();
+ compatClasses_.clear();
+ obsoleteClasses_.clear();
+ funcIndex_.clear();
+ legaleseTexts_.clear();
+ serviceClasses_.clear();
+ qmlClasses_.clear();
+
+ findAllClasses(treeRoot());
+ findAllFunctions(treeRoot());
+ findAllLegaleseTexts(treeRoot());
+ findAllNamespaces(treeRoot());
+ findAllSince(treeRoot());
+}
+
+/*!
+ Finds all the C++ class nodes and QML type nodes and
+ sorts them into maps.
+ */
+void QDocDatabase::findAllClasses(const InnerNode* node)
+{
+ NodeList::const_iterator c = node->childNodes().constBegin();
+ while (c != node->childNodes().constEnd()) {
+ if ((*c)->access() != Node::Private && (*c)->url().isEmpty()) {
+ if ((*c)->type() == Node::Class && !(*c)->doc().isEmpty()) {
+ QString className = (*c)->name();
+ if ((*c)->parent() &&
+ (*c)->parent()->type() == Node::Namespace &&
+ !(*c)->parent()->name().isEmpty())
+ className = (*c)->parent()->name()+"::"+className;
+
+ if (!(static_cast<const ClassNode *>(*c))->hideFromMainList()) {
+ if ((*c)->status() == Node::Compat) {
+ compatClasses_.insert(className, *c);
+ }
+ else if ((*c)->status() == Node::Obsolete) {
+ obsoleteClasses_.insert(className, *c);
+ }
+ else {
+ nonCompatClasses_.insert(className, *c);
+ if ((*c)->status() == Node::Main)
+ mainClasses_.insert(className, *c);
+ }
+ }
+
+ QString serviceName = (static_cast<const ClassNode *>(*c))->serviceName();
+ if (!serviceName.isEmpty())
+ serviceClasses_.insert(serviceName, *c);
+ }
+ else if ((*c)->type() == Node::Document &&
+ (*c)->subType() == Node::QmlClass &&
+ !(*c)->doc().isEmpty()) {
+ QString qmlTypeName = (*c)->name();
+ if (qmlTypeName.startsWith(QLatin1String("QML:")))
+ qmlClasses_.insert(qmlTypeName.mid(4),*c);
+ else
+ qmlClasses_.insert(qmlTypeName,*c);
+ }
+ else if ((*c)->isInnerNode()) {
+ findAllClasses(static_cast<InnerNode*>(*c));
+ }
+ }
+ ++c;
+ }
+}
+
+/*!
+ Finds all the function nodes
+ */
+void QDocDatabase::findAllFunctions(const InnerNode* node)
+{
+ NodeList::ConstIterator c = node->childNodes().constBegin();
+ while (c != node->childNodes().constEnd()) {
+ if ((*c)->access() != Node::Private) {
+ if ((*c)->isInnerNode() && (*c)->url().isEmpty()) {
+ findAllFunctions(static_cast<const InnerNode*>(*c));
+ }
+ else if ((*c)->type() == Node::Function) {
+ const FunctionNode* func = static_cast<const FunctionNode*>(*c);
+ if ((func->status() > Node::Obsolete) &&
+ !func->isInternal() &&
+ (func->metaness() != FunctionNode::Ctor) &&
+ (func->metaness() != FunctionNode::Dtor)) {
+ funcIndex_[(*c)->name()].insert((*c)->parent()->fullDocumentName(), *c);
+ }
+ }
+ }
+ ++c;
+ }
+}
+
+/*!
+ Finds all the nodes containing legalese text and puts them
+ in a map.
+ */
+void QDocDatabase::findAllLegaleseTexts(const InnerNode* node)
+{
+ NodeList::ConstIterator c = node->childNodes().constBegin();
+ while (c != node->childNodes().constEnd()) {
+ if ((*c)->access() != Node::Private) {
+ if (!(*c)->doc().legaleseText().isEmpty())
+ legaleseTexts_.insertMulti((*c)->doc().legaleseText(), *c);
+ if ((*c)->isInnerNode())
+ findAllLegaleseTexts(static_cast<const InnerNode *>(*c));
+ }
+ ++c;
+ }
+}
+
+/*!
+ Finds all the namespace nodes and puts them in an index.
+ */
+void QDocDatabase::findAllNamespaces(const InnerNode* node)
+{
+ NodeList::ConstIterator c = node->childNodes().constBegin();
+ while (c != node->childNodes().constEnd()) {
+ if ((*c)->access() != Node::Private) {
+ if ((*c)->isInnerNode() && (*c)->url().isEmpty()) {
+ findAllNamespaces(static_cast<const InnerNode *>(*c));
+ if ((*c)->type() == Node::Namespace) {
+ const NamespaceNode* nspace = static_cast<const NamespaceNode *>(*c);
+ // Ensure that the namespace's name is not empty (the root
+ // namespace has no name).
+ if (!nspace->name().isEmpty()) {
+ namespaceIndex_.insert(nspace->name(), *c);
+ }
+ }
+ }
+ }
+ ++c;
+ }
+}
+
+/*!
+ Finds all the nodes where a \e{since} command appeared in the
+ qdoc comment and sorts them into maps according to the kind of
+ node.
+
+ This function is used for generating the "New Classes... in x.y"
+ section on the \e{What's New in Qt x.y} page.
+ */
+void QDocDatabase::findAllSince(const InnerNode* node)
+{
+ NodeList::const_iterator child = node->childNodes().constBegin();
+ while (child != node->childNodes().constEnd()) {
+ QString sinceString = (*child)->since();
+ // Insert a new entry into each map for each new since string found.
+ if (((*child)->access() != Node::Private) && !sinceString.isEmpty()) {
+ NodeMultiMapMap::iterator nsmap = newSinceMaps_.find(sinceString);
+ if (nsmap == newSinceMaps_.end())
+ nsmap = newSinceMaps_.insert(sinceString,NodeMultiMap());
+
+ NodeMapMap::iterator ncmap = newClassMaps_.find(sinceString);
+ if (ncmap == newClassMaps_.end())
+ ncmap = newClassMaps_.insert(sinceString,NodeMap());
+
+ NodeMapMap::iterator nqcmap = newQmlTypeMaps_.find(sinceString);
+ if (nqcmap == newQmlTypeMaps_.end())
+ nqcmap = newQmlTypeMaps_.insert(sinceString,NodeMap());
+
+ if ((*child)->type() == Node::Function) {
+ // Insert functions into the general since map.
+ FunctionNode *func = static_cast<FunctionNode *>(*child);
+ if ((func->status() > Node::Obsolete) &&
+ (func->metaness() != FunctionNode::Ctor) &&
+ (func->metaness() != FunctionNode::Dtor)) {
+ nsmap.value().insert(func->name(),(*child));
+ }
+ }
+ else if ((*child)->url().isEmpty()) {
+ if ((*child)->type() == Node::Class && !(*child)->doc().isEmpty()) {
+ // Insert classes into the since and class maps.
+ QString className = (*child)->name();
+ if ((*child)->parent() && (*child)->parent()->type() == Node::Namespace &&
+ !(*child)->parent()->name().isEmpty()) {
+ className = (*child)->parent()->name()+"::"+className;
+ }
+ nsmap.value().insert(className,(*child));
+ ncmap.value().insert(className,(*child));
+ }
+ else if ((*child)->subType() == Node::QmlClass) {
+ // Insert QML elements into the since and element maps.
+ QString className = (*child)->name();
+ if ((*child)->parent() && (*child)->parent()->type() == Node::Namespace &&
+ !(*child)->parent()->name().isEmpty()) {
+ className = (*child)->parent()->name()+"::"+className;
+ }
+ nsmap.value().insert(className,(*child));
+ nqcmap.value().insert(className,(*child));
+ }
+ else if ((*child)->type() == Node::QmlProperty) {
+ // Insert QML properties into the since map.
+ QString propertyName = (*child)->name();
+ nsmap.value().insert(propertyName,(*child));
+ }
+ }
+ else {
+ // Insert external documents into the general since map.
+ QString name = (*child)->name();
+ if ((*child)->parent() && (*child)->parent()->type() == Node::Namespace &&
+ !(*child)->parent()->name().isEmpty()) {
+ name = (*child)->parent()->name()+"::"+name;
+ }
+ nsmap.value().insert(name,(*child));
+ }
+
+ // Recursively find child nodes with since commands.
+ if ((*child)->isInnerNode()) {
+ findAllSince(static_cast<InnerNode *>(*child));
+ }
+ }
+ ++child;
+ }
+}
+
+/*!
+ Find the \a key in the map of new class maps, and return a
+ reference to the value, which is a NodeMap. If \a key is not
+ found, return a reference to an empty NodeMap.
+ */
+const NodeMap& QDocDatabase::getClassMap(const QString& key) const
+{
+ NodeMapMap::const_iterator i = newClassMaps_.constFind(key);
+ if (i != newClassMaps_.constEnd())
+ return i.value();
+ return emptyNodeMap_;
+}
+
+/*!
+ Find the \a key in the map of new QML type maps, and return a
+ reference to the value, which is a NodeMap. If the \a key is not
+ found, return a reference to an empty NodeMap.
+ */
+const NodeMap& QDocDatabase::getQmlTypeMap(const QString& key) const
+{
+ NodeMapMap::const_iterator i = newQmlTypeMaps_.constFind(key);
+ if (i != newQmlTypeMaps_.constEnd())
+ return i.value();
+ return emptyNodeMap_;
+}
+
+/*!
+ Find the \a key in the map of new \e {since} maps, and return
+ a reference to the value, which is a NodeMultiMap. If \a key
+ is not found, return a reference to an empty NodeMultiMap.
+ */
+const NodeMultiMap& QDocDatabase::getSinceMap(const QString& key) const
+{
+ NodeMultiMapMap::const_iterator i = newSinceMaps_.constFind(key);
+ if (i != newSinceMaps_.constEnd())
+ return i.value();
+ return emptyNodeMultiMap_;
+}
+
+/*!
+ Performs several housekeeping algorithms that create
+ certain data structures and resolve lots of links, prior
+ to generating documentation.
+ */
+void QDocDatabase::resolveIssues() {
+ tree_->resolveGroups();
+ tree_->resolveTargets(tree_->root());
+ tree_->resolveCppToQmlLinks();
+}
+
+/*!
+ Look up group \a name in the map of groups. If found, populate
+ the node map \a group with the classes in the group that are
+ not marked internal or private.
+ */
+void QDocDatabase::getGroup(const QString& name, NodeMap& group) const
+{
+ group.clear();
+ NodeList values = tree_->groups().values(name);
+ for (int i=0; i<values.size(); ++i) {
+ const Node* n = values.at(i);
+ if ((n->status() != Node::Internal) && (n->access() != Node::Private)) {
+ group.insert(n->nameForLists(),n);
+ }
+ }
+}
+
+/*!
+ Searches the \a database for a node named \a target and returns
+ a pointer to it if found.
+ */
+const Node* QDocDatabase::resolveTarget(const QString& target,
+ const Node* relative,
+ const Node* self)
+{
+ const Node* node = 0;
+ if (target.endsWith("()")) {
+ QString funcName = target;
+ funcName.chop(2);
+ QStringList path = funcName.split("::");
+ const FunctionNode* fn = tree_->findFunctionNode(path, relative, Tree::SearchBaseClasses);
+ if (fn) {
+ /*
+ Why is this case not accepted?
+ */
+ if (fn->metaness() != FunctionNode::MacroWithoutParams)
+ node = fn;
+ }
+ }
+ else if (target.contains(QLatin1Char('#'))) {
+ // This error message is never printed; I think we can remove the case.
+ qDebug() << "qdoc: target case not handled:" << target;
+ }
+ else {
+ QStringList path = target.split("::");
+ int flags = Tree::SearchBaseClasses | Tree::SearchEnumValues | Tree::NonFunction;
+ node = tree_->findNode(path, relative, flags, self);
+ }
+ return node;
+}
+
+/*!
+ zzz
+ Is the atom necessary?
+ */
+const Node* QDocDatabase::findNodeForTarget(const QString& target,
+ const Node* relative,
+ const Atom* atom)
+{
+ const Node* node = 0;
+ if (target.isEmpty())
+ node = relative;
+ else if (target.endsWith(".html"))
+ node = tree_->root()->findChildNodeByNameAndType(target, Node::Document);
+ else {
+ node = resolveTarget(target, relative);
+ if (!node)
+ node = tree_->findDocNodeByTitle(target, relative);
+ if (!node && atom) {
+ qDebug() << "USING ATOM!";
+ node = tree_->findUnambiguousTarget(target, *const_cast<Atom**>(&atom), relative);
+ }
+ }
+ return node;
+}
+
+QT_END_NAMESPACE
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDOCDATABASE_H
+#define QDOCDATABASE_H
+
+#include <QString>
+#include <QMultiMap>
+#include "tree.h"
+
+QT_BEGIN_NAMESPACE
+
+typedef QMap<QString, DocNode*> DocNodeMap;
+typedef QMap<QString, QmlClassNode*> QmlTypeMap;
+typedef QMap<QString, NodeMap> NodeMapMap;
+typedef QMap<QString, NodeMultiMap> NodeMultiMapMap;
+typedef QMultiMap<QString, Node*> QDocMultiMap;
+typedef QMap<Text, const Node*> TextToNodeMap;
+
+class QDocDatabase
+{
+ public:
+ static QDocDatabase* qdocDB();
+ static void destroyQdocDB();
+ ~QDocDatabase();
+
+ const DocNodeMap& modules() const { return modules_; }
+ const DocNodeMap& qmlModules() const { return qmlModules_; }
+ DocNode* addModule(const QString& name);
+ DocNode* addQmlModule(const QString& name);
+ DocNode* addToModule(const QString& name, Node* node);
+ DocNode* addToQmlModule(const QString& moduleName, Node* node);
+ DocNode* findModule(const QString& qmlModuleName, bool addIfNotFound = false);
+ DocNode* findQmlModule(const QString& name, bool addIfNotFound = false);
+ QmlClassNode* findQmlType(const QString& qmid, const QString& name) const;
+
+ void findAllClasses(const InnerNode *node);
+ void findAllFunctions(const InnerNode *node);
+ void findAllLegaleseTexts(const InnerNode *node);
+ void findAllNamespaces(const InnerNode *node);
+ void findAllSince(const InnerNode *node);
+ void buildCollections();
+
+ // special collection access functions
+ NodeMap& getCppClasses() { return nonCompatClasses_; }
+ NodeMap& getMainClasses() { return mainClasses_; }
+ NodeMap& getCompatibilityClasses() { return compatClasses_; }
+ NodeMap& getObsoleteClasses() { return obsoleteClasses_; }
+ NodeMap& getNamespaces() { return namespaceIndex_; }
+ NodeMap& getServiceClasses() { return serviceClasses_; }
+ NodeMap& getQmlTypes() { return qmlClasses_; }
+ NodeMapMap& getFunctionIndex() { return funcIndex_; }
+ TextToNodeMap& getLegaleseTexts() { return legaleseTexts_; }
+ const NodeMultiMap& groups() const { return tree_->groups(); }
+ const NodeList getGroup(const QString& name) const { return tree_->groups().values(name); }
+ void getGroup(const QString& name, NodeMap& group) const;
+ const NodeMap& getClassMap(const QString& key) const;
+ const NodeMap& getQmlTypeMap(const QString& key) const;
+ const NodeMultiMap& getSinceMap(const QString& key) const;
+
+ const Node* resolveTarget(const QString& target, const Node* relative, const Node* self=0);
+ const Node* findNodeForTarget(const QString& target, const Node* relative, const Atom* atom=0);
+
+ /* convenience functions
+ Many of these will be either eliminated or replaced.
+ */
+ Tree* tree() { return tree_; }
+ QString version() const { return tree_->version(); }
+ NamespaceNode* treeRoot() { return tree_->root(); }
+ void setVersion(const QString& version) { tree_->setVersion(version); }
+ void resolveInheritance() { tree_->resolveInheritance(); }
+ void readIndexes(const QStringList& indexFiles) { tree_->readIndexes(indexFiles); }
+ void resolveIssues();
+ void generateTagFile(const QString& name) { if (!name.isEmpty()) tree_->generateTagFile(name); }
+ void addToGroup(Node* node, const QString& group) { tree_->addToGroup(node, group); }
+ void addToPublicGroup(Node* node, const QString& group) { tree_->addToPublicGroup(node, group); }
+ void fixInheritance() { tree_->fixInheritance(); }
+ void resolveProperties() { tree_->resolveProperties(); }
+
+ const Node* findNode(const QStringList& path) { return tree_->findNode(path); }
+ ClassNode* findClassNode(const QStringList& path) { return tree_->findClassNode(path); }
+ NamespaceNode* findNamespaceNode(const QStringList& path) { return tree_->findNamespaceNode(path); }
+
+ DocNode* findGroupNode(const QStringList& path) { return tree_->findGroupNode(path); }
+ NameCollisionNode* findCollisionNode(const QString& name) const {
+ return tree_->findCollisionNode(name);
+ }
+
+ const DocNode* findDocNodeByTitle(const QString& title, const Node* relative=0) const {
+ return tree_->findDocNodeByTitle(title, relative);
+ }
+ const Node* findUnambiguousTarget(const QString& target, Atom* &atom, const Node* relative) const {
+ return tree_->findUnambiguousTarget(target, atom, relative);
+ }
+ Atom* findTarget(const QString& target, const Node* node) const {
+ return tree_->findTarget(target, node);
+ }
+ void generateIndex(const QString& fileName,
+ const QString& url,
+ const QString& title,
+ Generator* g,
+ bool generateInternalNodes = false) {
+ tree_->generateIndex(fileName, url, title, g, generateInternalNodes);
+ }
+ FunctionNode* findFunctionNode(const QStringList& parentPath, const FunctionNode* clone) {
+ return tree_->findFunctionNode(parentPath, clone);
+ }
+ Node* findNodeByNameAndType(const QStringList& path, Node::Type type, Node::SubType subtype){
+ return tree_->findNodeByNameAndType(path, type, subtype, 0);
+ }
+ NameCollisionNode* checkForCollision(const QString& name) const {
+ return tree_->checkForCollision(name);
+ }
+ void addBaseClass(ClassNode* subclass,
+ Node::Access access,
+ const QStringList& basePath,
+ const QString& dataTypeWithTemplateArgs,
+ InnerNode* parent) {
+ tree_->addBaseClass(subclass, access, basePath, dataTypeWithTemplateArgs, parent);
+ }
+ void addPropertyFunction(PropertyNode* property,
+ const QString& funcName,
+ PropertyNode::FunctionRole funcRole) {
+ tree_->addPropertyFunction(property, funcName, funcRole);
+ }
+
+ /* debugging functions */
+ void printModules() const;
+ void printQmlModules() const;
+
+ private:
+ QDocDatabase();
+ QDocDatabase(QDocDatabase const& ) { }; // copy constructor is private
+ QDocDatabase& operator=(QDocDatabase const& ); // assignment operator is private
+
+ private:
+ static QDocDatabase* qdocDB_;
+ QDocMultiMap masterMap_;
+ Tree* tree_;
+ DocNodeMap modules_;
+ DocNodeMap qmlModules_;
+ QmlTypeMap qmlTypeMap_;
+
+ NodeMap nonCompatClasses_;
+ NodeMap mainClasses_;
+ NodeMap compatClasses_;
+ NodeMap obsoleteClasses_;
+ NodeMap namespaceIndex_;
+ NodeMap serviceClasses_;
+ NodeMap qmlClasses_;
+ NodeMapMap newClassMaps_;
+ NodeMapMap newQmlTypeMaps_;
+ NodeMultiMapMap newSinceMaps_;
+ NodeMapMap funcIndex_;
+ TextToNodeMap legaleseTexts_;
+};
+
+QT_END_NAMESPACE
+
+#endif
return Atom::Qml;
}
-/*!
- Returns the name of the \a node. Method names include are returned with a
- trailing set of parentheses.
- */
-QString QmlCodeMarker::plainName(const Node *node)
-{
- QString name = node->name();
- if (node->type() == Node::QmlMethod)
- name += "()";
- return name;
-}
-
-QString QmlCodeMarker::plainFullName(const Node *node, const Node *relative)
-{
- if (node->name().isEmpty()) {
- return "global";
- }
- else {
- QString fullName;
- while (node) {
- fullName.prepend(plainName(node));
- if (node->parent() == relative ||
- node->parent()->subType() == Node::Collision ||
- node->parent()->name().isEmpty())
- break;
- fullName.prepend("::");
- node = node->parent();
- }
- return fullName;
- }
-}
-
QString QmlCodeMarker::markedUpCode(const QString &code,
const Node *relative,
const Location &location)
virtual bool recognizeExtension(const QString &ext);
virtual bool recognizeLanguage(const QString &language);
virtual Atom::Type atomType() const;
- virtual QString plainName(const Node *node);
- virtual QString plainFullName(const Node *node, const Node *relative);
virtual QString markedUpCode(const QString &code,
const Node *relative,
const Location &location);
#include "qqmljsast_p.h"
#include "qqmljsastvisitor_p.h"
-
#include "qmlcodeparser.h"
#include "node.h"
-#include "tree.h"
#include "config.h"
#include "qmlvisitor.h"
#include <qdebug.h>
#define COMMAND_QMLBASICTYPE Doc::alias("qmlbasictype")
#define COMMAND_QMLMODULE Doc::alias("qmlmodule")
+/*!
+ Constructs the QML code parser.
+ */
QmlCodeParser::QmlCodeParser()
{
}
+/*!
+ Destroys the QML code parser.
+ */
QmlCodeParser::~QmlCodeParser()
{
}
}
/*!
- Deletes the lexer and parser created by the constructor.
+ Terminates the QML code parser. Deletes the lexer and parser
+ created by the constructor.
*/
void QmlCodeParser::terminateParser()
{
}
/*!
- Returns a filter string of "*.qml".
+ Returns a string list containing "*.qml". This is the only
+ file type parsed by the QMLN parser.
*/
QStringList QmlCodeParser::sourceFileNameFilter()
{
}
/*!
- Parses the source file at \a filePath, creating nodes as
- needed and inserting them into the \a tree. \a location is
- used for error reporting.
+ Parses the source file at \a filePath and inserts the contents
+ into the database. The \a location is used for error reporting.
- If it can't open the file at \a filePath, it reports an
- error and returns without doing anything.
+ If it can't open the file at \a filePath, it reports an error
+ and returns without doing anything.
*/
-void QmlCodeParser::parseSourceFile(const Location& location,
- const QString& filePath,
- Tree *tree)
+void QmlCodeParser::parseSourceFile(const Location& location, const QString& filePath)
{
QFile in(filePath);
currentFile_ = filePath;
QmlDocVisitor visitor(filePath,
newCode,
&engine,
- tree,
metacommandsAllowed,
topicCommandsAllowed);
QQmlJS::AST::Node::accept(ast, &visitor);
}
/*!
- This function is called when the parser finishes parsing
- the file, but in this case the function does nothing.
+ Performs cleanup after qdoc is done parsing all the QML files.
+ Currently, no cleanup is required.
*/
-void QmlCodeParser::doneParsingSourceFiles(Tree *)
+void QmlCodeParser::doneParsingSourceFiles()
{
}
virtual void terminateParser();
virtual QString language();
virtual QStringList sourceFileNameFilter();
- virtual void parseSourceFile(const Location& location,
- const QString& filePath, Tree *tree);
- virtual void doneParsingSourceFiles(Tree *tree);
+ virtual void parseSourceFile(const Location& location, const QString& filePath);
+ virtual void doneParsingSourceFiles();
/* Copied from src/declarative/qml/qdeclarativescriptparser.cpp */
void extractPragmas(QString &script);
#include "node.h"
#include "codeparser.h"
#include "qmlvisitor.h"
+#include "qdocdatabase.h"
QT_BEGIN_NAMESPACE
QmlDocVisitor::QmlDocVisitor(const QString &filePath,
const QString &code,
QQmlJS::Engine *engine,
- Tree *tree,
QSet<QString> &commands,
QSet<QString> &topics)
: nestingLevel(0)
this->name = QFileInfo(filePath).baseName();
document = code;
this->engine = engine;
- this->tree = tree;
this->commands = commands;
this->topics = topics;
- current = tree->root();
+ current = QDocDatabase::qdocDB()->treeRoot();
}
/*!
Node* node,
Doc& doc)
{
+ QDocDatabase* qdb = QDocDatabase::qdocDB();
+
const TopicList& topicsUsed = doc.topicsUsed();
if (topicsUsed.size() > 0) {
if (node->type() == Node::QmlProperty) {
node->setStatus(Node::Deprecated);
}
else if (command == COMMAND_INQMLMODULE) {
- node->setQmlModule(args[0]);
- DocNode* dn = DocNode::lookupQmlModuleNode(tree, args[0]);
- dn->addQmlModuleMember(node);
- QString qmid = node->qmlModuleIdentifier();
- QmlClassNode* qcn = static_cast<QmlClassNode*>(node);
- QmlClassNode::insertQmlModuleMember(qmid, qcn);
+ qdb->addToQmlModule(args[0].first,node);
}
else if (command == COMMAND_QMLINHERITS) {
if (node->name() == args[0].first)
else if ((command == COMMAND_INGROUP) && !args.isEmpty()) {
ArgList::ConstIterator argsIter = args.constBegin();
while (argsIter != args.constEnd()) {
- tree->addToGroup(node, argsIter->first);
+ QDocDatabase::qdocDB()->addToGroup(node, argsIter->first);
++argsIter;
}
}
}
/*!
- Begin the visit of the object \a definition, recording it in a tree
- structure. Increment the object nesting level, which is used to
- test whether we are at the public API level. The public level is
- level 1.
+ Begin the visit of the object \a definition, recording it in the
+ qdoc database. Increment the object nesting level, which is used
+ to test whether we are at the public API level. The public level
+ is level 1.
*/
bool QmlDocVisitor::visit(QQmlJS::AST::UiObjectDefinition *definition)
{
QmlDocVisitor(const QString &filePath,
const QString &code,
QQmlJS::Engine *engine,
- Tree *tree,
QSet<QString> &commands,
QSet<QString> &topics);
virtual ~QmlDocVisitor();
#include "node.h"
#include "text.h"
#include "tree.h"
+#include "qdocdatabase.h"
#include <limits.h>
#include <qdebug.h>
\class Tree
This class constructs and maintains a tree of instances of
- Node and its many subclasses.
+ the subclasses of Node.
+
+ This class is now private. Only class QDocDatabase has access.
+ Please don't change this. If you must access class Tree, do it
+ though the pointer to the singleton QDocDatabase.
*/
/*!
- The default constructor is the only constructor.
+ Constructs the singleton tree. \a qdb is the pointer to the
+ qdoc database that is constructing the tree. This might not
+ be necessary, and it might be removed later.
*/
-Tree::Tree()
- : roo(0, QString())
+Tree::Tree(QDocDatabase* qdb)
+ : qdb_(qdb), root_(0, QString())
{
priv = new TreePrivate;
}
If the anser is yes, the reference identifies a QML
class node.
*/
- if (qml && path.size() >= 2) {
- QmlClassNode* qcn = QmlClassNode::lookupQmlTypeNode(path[0], path[1]);
+ if (qml && path.size() >= 2 && !path[0].isEmpty()) {
+ QmlClassNode* qcn = qdb_->findQmlType(path[0], path[1]);
if (qcn) {
node = qcn;
if (path.size() == 2)
}
/*!
- Find the QML class node for the specified \a module and \a name
- identifiers. The \a module identifier may be empty. If the module
- identifier is empty, then begin by finding the DocNode that has
- the specified \a name. If that DocNode is a QML class, return it.
- If it is a collision node, return its current child, if the current
- child is a QML class. If the collision node does not have a child
- that is a QML class node, return 0.
+ Find the Qml type node named \a path. Begin the search at the
+ \a start node. If the \a start node is 0, begin the search
+ at the root of the tree. Only a Qml type node named \a path is
+ acceptible. If one is not found, 0 is returned.
*/
-QmlClassNode* Tree::findQmlClassNode(const QString& module, const QString& name)
+QmlClassNode* Tree::findQmlTypeNode(const QStringList& path)
{
- if (module.isEmpty()) {
- Node* n = findQmlClassNode(QStringList(name));
- if (n) {
- if (n->subType() == Node::QmlClass)
- return static_cast<QmlClassNode*>(n);
- else if (n->subType() == Node::Collision) {
- NameCollisionNode* ncn;
- ncn = static_cast<NameCollisionNode*>(n);
- return static_cast<QmlClassNode*>(ncn->findAny(Node::Document,Node::QmlClass));
- }
- }
- return 0;
+ /*
+ If the path contains one or two double colons ("::"),
+ check first to see if the first two path strings refer
+ to a QML element. If they do, path[0] will be the QML
+ module identifier, and path[1] will be the QML type.
+ If the anser is yes, the reference identifies a QML
+ class node.
+ */
+ if (path.size() >= 2 && !path[0].isEmpty()) {
+ QmlClassNode* qcn = qdb_->findQmlType(path[0], path[1]);
+ if (qcn)
+ return qcn;
}
- return QmlClassNode::lookupQmlTypeNode(module, name);
+ return static_cast<QmlClassNode*>(findNodeRecursive(path, 0, root(), Node::Document, Node::QmlClass));
}
/*!
it is a reference to a QML method, first look up the
QML class node in the QML module map.
*/
- if (path.size() == 3) {
- QmlClassNode* qcn = QmlClassNode::lookupQmlTypeNode(path[0], path[1]);
+ if (path.size() == 3 && !path[0].isEmpty()) {
+ QmlClassNode* qcn = qdb_->findQmlType(path[0], path[1]);
if (qcn) {
return static_cast<const FunctionNode*>(qcn->findFunctionNode(path[2]));
}
int findFlags) const
{
const Node* parent = findNode(parentPath, relative, findFlags);
- if (parent == 0 || !parent->isInnerNode()) {
+ if (parent == 0 || !parent->isInnerNode())
return 0;
- }
- else {
- return ((InnerNode*)parent)->findFunctionNode(clone);
- }
+ return ((InnerNode*)parent)->findFunctionNode(clone);
}
//findNode(parameter.leftType().split("::"), 0, SearchBaseClasses|NonFunction);
/*!
Returns the group map.
*/
-NodeMultiMap Tree::groups() const
+const NodeMultiMap& Tree::groups() const
{
return priv->groupMap;
}
if (i.value()->access() == Node::Private)
continue;
- Node* n = findGroupNode(QStringList(i.key()));
+ DocNode* n = findGroupNode(QStringList(i.key()));
if (n)
- n->addGroupMember(i.value());
+ n->addMember(i.value());
}
}
void Tree::resolveCppToQmlLinks()
{
- foreach (Node* child, roo.childNodes()) {
+ foreach (Node* child, root_.childNodes()) {
if (child->type() == Node::Document && child->subType() == Node::QmlClass) {
QmlClassNode* qcn = static_cast<QmlClassNode*>(child);
ClassNode* cn = const_cast<ClassNode*>(qcn->classNode());
}
/*!
- For each QML class node in the tree, determine whether
- it inherits a QML base class and, if so, which one, and
- store that pointer in the QML class node's state.
- */
-void Tree::resolveQmlInheritance()
-{
-
- foreach (Node* child, roo.childNodes()) {
- if (child->type() == Node::Document) {
- if (child->subType() == Node::QmlClass) {
- QmlClassNode* qcn = static_cast<QmlClassNode*>(child);
- qcn->resolveInheritance(this);
- }
- else if (child->subType() == Node::Collision) {
- NameCollisionNode* ncn = static_cast<NameCollisionNode*>(child);
- foreach (Node* child, ncn->childNodes()) {
- if (child->type() == Node::Document) {
- if (child->subType() == Node::QmlClass) {
- QmlClassNode* qcn = static_cast<QmlClassNode*>(child);
- qcn->resolveInheritance(this);
- }
- }
- }
- }
- }
- }
-}
-
-/*!
*/
void Tree::fixInheritance(NamespaceNode* rootNode)
{
QmlPropertyNode* qpn = static_cast<QmlPropertyNode*>(node);
writer.writeAttribute("type", qpn->dataType());
writer.writeAttribute("attached", qpn->isAttached() ? "true" : "false");
- writer.writeAttribute("writable", qpn->isWritable(this) ? "true" : "false");
+ writer.writeAttribute("writable", qpn->isWritable(qdb_) ? "true" : "false");
}
break;
case Node::Property:
}
/*!
- Find the Qml class node named \a path. Begin the search at the
- \a start node. If the \a start node is 0, begin the search
- at the root of the tree. Only a Qml class node named \a path is
- acceptible. If one is not found, 0 is returned.
+ Find the Namespace node named \a path. Begin the search at
+ the root of the tree. Only a Namespace node named \a path
+ is acceptible. If one is not found, 0 is returned.
*/
-QmlClassNode* Tree::findQmlClassNode(const QStringList& path, Node* start)
+NamespaceNode* Tree::findNamespaceNode(const QStringList& path)
{
- /*
- If the path contains one or two double colons ("::"),
- check first to see if the first two path strings refer
- to a QML element. If they do, path[0] will be the QML
- module identifier, and path[1] will be the QML type.
- If the anser is yes, the reference identifies a QML
- class node.
- */
- if (path.size() >= 2) {
- QmlClassNode* qcn = QmlClassNode::lookupQmlTypeNode(path[0], path[1]);
- if (qcn)
- return qcn;
- }
-
- if (!start)
- start = const_cast<NamespaceNode*>(root());
- return static_cast<QmlClassNode*>(findNodeRecursive(path, 0, start, Node::Document, Node::QmlClass));
-}
-
-/*!
- Find the Namespace node named \a path. Begin the search at the
- \a start node. If the \a start node is 0, begin the search
- at the root of the tree. Only a Namespace node named \a path is
- acceptible. If one is not found, 0 is returned.
- */
-NamespaceNode* Tree::findNamespaceNode(const QStringList& path, Node* start)
-{
- if (!start)
- start = const_cast<NamespaceNode*>(root());
+ Node* start = const_cast<NamespaceNode*>(root());
return static_cast<NamespaceNode*>(findNodeRecursive(path, 0, start, Node::Namespace, Node::NoSubType));
}
class Generator;
class QStringList;
class TreePrivate;
+class QDocDatabase;
class Tree
{
-public:
+ private:
+ friend class QDocDatabase;
+
enum FindFlag { SearchBaseClasses = 0x1,
SearchEnumValues = 0x2,
NonFunction = 0x4 };
- Tree();
+ Tree(QDocDatabase* qdb);
~Tree();
EnumNode* findEnumNode(const QStringList& path, Node* start = 0);
ClassNode* findClassNode(const QStringList& path, Node* start = 0);
- QmlClassNode* findQmlClassNode(const QStringList& path, Node* start = 0);
- NamespaceNode* findNamespaceNode(const QStringList& path, Node* start = 0);
+ QmlClassNode* findQmlTypeNode(const QStringList& path);
+ NamespaceNode* findNamespaceNode(const QStringList& path);
DocNode* findGroupNode(const QStringList& path, Node* start = 0);
DocNode* findQmlModuleNode(const QStringList& path, Node* start = 0);
int findFlags = 0,
const Node* self=0) const;
- private:
const Node* findNode(const QStringList& path,
const Node* start,
int findFlags,
const Node* self,
bool qml) const;
- public:
- QmlClassNode* findQmlClassNode(const QString& module, const QString& name);
NameCollisionNode* checkForCollision(const QString& name) const;
NameCollisionNode* findCollisionNode(const QString& name) const;
FunctionNode *findFunctionNode(const QStringList &path,
Node::Access access,
const QStringList &basePath,
const QString &dataTypeWithTemplateArgs,
- InnerNode *parent = 0);
+ InnerNode *parent);
void addPropertyFunction(PropertyNode *property,
const QString &funcName,
PropertyNode::FunctionRole funcRole);
void addToGroup(Node *node, const QString &group);
void addToPublicGroup(Node *node, const QString &group);
void addToQmlModule(Node* node);
- NodeMultiMap groups() const;
+ const NodeMultiMap& groups() const;
QMultiMap<QString,QString> publicGroups() const;
void resolveInheritance(NamespaceNode *rootNode = 0);
void resolveProperties();
void resolveCppToQmlLinks();
void fixInheritance(NamespaceNode *rootNode = 0);
void setVersion(const QString &version) { vers = version; }
- NamespaceNode *root() { return &roo; }
+ NamespaceNode *root() { return &root_; }
QString version() const { return vers; }
const FunctionNode *findFunctionNode(const QStringList &path,
const DocNode *findDocNodeByTitle(const QString &title, const Node* relative = 0) const;
const Node *findUnambiguousTarget(const QString &target, Atom *&atom, const Node* relative) const;
Atom *findTarget(const QString &target, const Node *node) const;
- const NamespaceNode *root() const { return &roo; }
+ const NamespaceNode *root() const { return &root_; }
void readIndexes(const QStringList &indexFiles);
bool generateIndexSection(QXmlStreamWriter& writer, Node* node, bool generateInternalNodes = false);
void generateIndexSections(QXmlStreamWriter& writer, Node* node, bool generateInternalNodes = false);
const InnerNode *inner);
void generateTagFile(const QString &fileName);
void addExternalLink(const QString &url, const Node *relative);
- void resolveQmlInheritance();
-private:
void resolveInheritance(int pass, ClassNode *classe);
FunctionNode *findVirtualFunctionInBaseClasses(ClassNode *classe,
FunctionNode *clone);
void resolveIndex();
private:
- NamespaceNode roo;
+ QDocDatabase* qdb_;
+ NamespaceNode root_;
QString vers;
Generator* gen_;
TreePrivate *priv;