summaryrefslogtreecommitdiffstats
path: root/tools/qdoc3
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-07-22 18:00:32 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-07-22 18:00:32 (GMT)
commit3d9f5b56f1c26c2bccedae04eb9536fed3474d43 (patch)
treeb5530bab26b47f6a5b19d8970818e88403f2fd68 /tools/qdoc3
parent71cc2f69171f5dd6d8ae094239230362fc8db081 (diff)
parent0b68204919a81c2aeca7924711cd5e159dca7903 (diff)
downloadQt-3d9f5b56f1c26c2bccedae04eb9536fed3474d43.zip
Qt-3d9f5b56f1c26c2bccedae04eb9536fed3474d43.tar.gz
Qt-3d9f5b56f1c26c2bccedae04eb9536fed3474d43.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/oslo-staging-1: If the QEventDispatcherGlibc causes warnings, it should say so Remove a warning message that no longer appears after all on Windows Drag & Drop failing in itemviews on Cocoa. qdoc: Removed debug code. qdoc: Fixed reporting of read-only status for QML properties. Fix the smallFont test failure for Mac and Linux Revert "Compile fix for MSVC" Compile fix for MSVC Improve QAccessible for QAccessibleTabBar Improve QAccessible for QTabBar fix the export macros for the QtDBus module rebuild configure.exe make "configure -qt-gif" work again on Windows Fix a typo in harfbuzz thai line breaking. Ensure that font sizes that are > 0 and < 1 are still respected
Diffstat (limited to 'tools/qdoc3')
-rw-r--r--tools/qdoc3/cppcodeparser.cpp32
-rw-r--r--tools/qdoc3/cppcodeparser.h1
-rw-r--r--tools/qdoc3/ditaxmlgenerator.cpp2
-rw-r--r--tools/qdoc3/htmlgenerator.cpp12
-rw-r--r--tools/qdoc3/node.cpp218
-rw-r--r--tools/qdoc3/node.h18
-rw-r--r--tools/qdoc3/test/qt-cpp-ignore.qdocconf4
-rw-r--r--tools/qdoc3/tokenizer.cpp6
-rw-r--r--tools/qdoc3/tokenizer.h2
-rw-r--r--tools/qdoc3/tree.cpp9
10 files changed, 262 insertions, 42 deletions
diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp
index d5108fd..a120e45 100644
--- a/tools/qdoc3/cppcodeparser.cpp
+++ b/tools/qdoc3/cppcodeparser.cpp
@@ -1120,6 +1120,17 @@ bool CppCodeParser::match(int target)
}
/*!
+ Skip to \a target. If \a target is found before the end
+ of input, return true. Otherwise return false.
+ */
+bool CppCodeParser::skipTo(int target)
+{
+ while ((tok != Tok_Eoi) && (tok != target))
+ readToken();
+ return (tok == target ? true : false);
+}
+
+/*!
If the current token is one of the keyword thingees that
are used in Qt, skip over it to the next token and return
true. Otherwise just return false without reading the
@@ -1362,7 +1373,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent,
if (!matchDataType(&returnType)) {
if (tokenizer->parsingFnOrMacro()
- && (match(Tok_Q_DECLARE_FLAGS) || match(Tok_Q_PROPERTY)))
+ && (match(Tok_Q_DECLARE_FLAGS) ||
+ match(Tok_Q_PROPERTY) ||
+ match(Tok_Q_PRIVATE_PROPERTY)))
returnType = CodeChunk(previousLexeme());
else {
return false;
@@ -1796,11 +1809,19 @@ bool CppCodeParser::matchTypedefDecl(InnerNode *parent)
bool CppCodeParser::matchProperty(InnerNode *parent)
{
- if (!match(Tok_Q_PROPERTY) &&
- !match(Tok_Q_OVERRIDE) &&
- !match(Tok_QDOC_PROPERTY))
+ int expected_tok = Tok_LeftParen;
+ if (match(Tok_Q_PRIVATE_PROPERTY)) {
+ expected_tok = Tok_Comma;
+ if (!skipTo(Tok_Comma))
+ return false;
+ }
+ else if (!match(Tok_Q_PROPERTY) &&
+ !match(Tok_Q_OVERRIDE) &&
+ !match(Tok_QDOC_PROPERTY)) {
return false;
- if (!match(Tok_LeftParen))
+ }
+
+ if (!match(expected_tok))
return false;
QString name;
@@ -1949,6 +1970,7 @@ bool CppCodeParser::matchDeclList(InnerNode *parent)
break;
case Tok_Q_OVERRIDE:
case Tok_Q_PROPERTY:
+ case Tok_Q_PRIVATE_PROPERTY:
case Tok_QDOC_PROPERTY:
matchProperty(parent);
break;
diff --git a/tools/qdoc3/cppcodeparser.h b/tools/qdoc3/cppcodeparser.h
index 3c53f72..55d9ddf 100644
--- a/tools/qdoc3/cppcodeparser.h
+++ b/tools/qdoc3/cppcodeparser.h
@@ -119,6 +119,7 @@ class CppCodeParser : public CodeParser
QString previousLexeme();
QString lexeme();
bool match(int target);
+ bool skipTo(int target);
bool matchCompat();
bool matchTemplateAngles(CodeChunk *type = 0);
bool matchTemplateHeader();
diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp
index d7a9c9e..4789c67 100644
--- a/tools/qdoc3/ditaxmlgenerator.cpp
+++ b/tools/qdoc3/ditaxmlgenerator.cpp
@@ -4210,7 +4210,7 @@ void DitaXmlGenerator::generateDetailedQmlMember(const Node *node,
out() << "<td><p>";
//out() << "<tr><td>"; // old
out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
- if (!qpn->isWritable())
+ if (!qpn->isWritable(myTree))
out() << "<span class=\"qmlreadonly\">read-only</span>";
if (qpgn->isDefault())
out() << "<span class=\"qmldefault\">default</span>";
diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp
index e840a7f..1b62dc4 100644
--- a/tools/qdoc3/htmlgenerator.cpp
+++ b/tools/qdoc3/htmlgenerator.cpp
@@ -4107,8 +4107,10 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node,
out() << "<td class=\"tblQmlPropNode\"><p>";
out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
- if (!qpn->isWritable())
+
+ if (!qpn->isWritable(myTree)) {
out() << "<span class=\"qmlreadonly\">read-only</span>";
+ }
if (qpgn->isDefault())
out() << "<span class=\"qmldefault\">default</span>";
generateQmlItem(qpn, relative, marker, false);
@@ -4124,10 +4126,10 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node,
out() << "<div class=\"qmlproto\">";
out() << "<table class=\"qmlname\">";
//out() << "<tr>";
- if (++numTableRows % 2 == 1)
- out() << "<tr class=\"odd\">";
- else
- out() << "<tr class=\"even\">";
+ if (++numTableRows % 2 == 1)
+ out() << "<tr class=\"odd\">";
+ else
+ out() << "<tr class=\"even\">";
out() << "<td class=\"tblQmlFuncNode\"><p>";
out() << "<a name=\"" + refForNode(qsn) + "\"></a>";
generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false);
diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp
index 0ca4870..259641e 100644
--- a/tools/qdoc3/node.cpp
+++ b/tools/qdoc3/node.cpp
@@ -44,6 +44,8 @@
*/
#include "node.h"
+#include "tree.h"
+#include "codemarker.h"
#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -171,6 +173,32 @@ QString Node::accessString() const
return "public";
}
+/*!
+ Extract a class name from the type \a string and return it.
+ */
+QString Node::extractClassName(const QString &string) const
+{
+ QString result;
+ for (int i=0; i<=string.size(); ++i) {
+ QChar ch;
+ if (i != string.size())
+ ch = string.at(i);
+
+ QChar lower = ch.toLower();
+ if ((lower >= QLatin1Char('a') && lower <= QLatin1Char('z')) ||
+ ch.digitValue() >= 0 ||
+ ch == QLatin1Char('_') ||
+ ch == QLatin1Char(':')) {
+ result += ch;
+ }
+ else if (!result.isEmpty()) {
+ if (result != QLatin1String("const"))
+ return result;
+ result.clear();
+ }
+ }
+ return result;
+}
/*!
Returns a string representing the access specifier.
@@ -426,6 +454,9 @@ void InnerNode::setOverload(const FunctionNode *func, bool overlode)
}
/*!
+ Mark all child nodes that have no documentation as having
+ private access and internal status. qdoc will then ignore
+ them for documentation purposes.
*/
void InnerNode::makeUndocumentedChildrenInternal()
{
@@ -831,6 +862,7 @@ NamespaceNode::NamespaceNode(InnerNode *parent, const QString& name)
/*!
\class ClassNode
+ \brief This class represents a C++ class.
*/
/*!
@@ -850,8 +882,8 @@ void ClassNode::addBaseClass(Access access,
ClassNode *node,
const QString &dataTypeWithTemplateArgs)
{
- bas.append(RelatedClass(access, node, dataTypeWithTemplateArgs));
- node->der.append(RelatedClass(access, this));
+ bases.append(RelatedClass(access, node, dataTypeWithTemplateArgs));
+ node->derived.append(RelatedClass(access, this));
}
/*!
@@ -859,16 +891,16 @@ void ClassNode::addBaseClass(Access access,
void ClassNode::fixBaseClasses()
{
int i;
-
i = 0;
- while (i < bas.size()) {
- ClassNode *baseClass = bas.at(i).node;
- if (baseClass->access() == Node::Private) {
- bas.removeAt(i);
-
- const QList<RelatedClass> &basesBases = baseClass->baseClasses();
- for (int j = basesBases.size() - 1; j >= 0; --j)
- bas.insert(i, basesBases.at(j));
+ while (i < bases.size()) {
+ ClassNode* bc = bases.at(i).node;
+ if (bc->access() == Node::Private) {
+ RelatedClass rc = bases.at(i);
+ bases.removeAt(i);
+ ignoredBases.append(rc);
+ const QList<RelatedClass> &bb = bc->baseClasses();
+ for (int j = bb.size() - 1; j >= 0; --j)
+ bases.insert(i, bb.at(j));
}
else {
++i;
@@ -876,15 +908,13 @@ void ClassNode::fixBaseClasses()
}
i = 0;
- while (i < der.size()) {
- ClassNode *derivedClass = der.at(i).node;
- if (derivedClass->access() == Node::Private) {
- der.removeAt(i);
-
- const QList<RelatedClass> &dersDers =
- derivedClass->derivedClasses();
- for (int j = dersDers.size() - 1; j >= 0; --j)
- der.insert(i, dersDers.at(j));
+ while (i < derived.size()) {
+ ClassNode* dc = derived.at(i).node;
+ if (dc->access() == Node::Private) {
+ derived.removeAt(i);
+ const QList<RelatedClass> &dd = dc->derivedClasses();
+ for (int j = dd.size() - 1; j >= 0; --j)
+ derived.insert(i, dd.at(j));
}
else {
++i;
@@ -893,6 +923,16 @@ void ClassNode::fixBaseClasses()
}
/*!
+ Search the child list to find the property node with the
+ specified \a name.
+ */
+const PropertyNode* ClassNode::findPropertyNode(const QString& name) const
+{
+ const Node* n = findNode(name,Node::Property);
+ return (n ? static_cast<const PropertyNode*>(n) : 0);
+}
+
+/*!
\class FakeNode
*/
@@ -1585,6 +1625,144 @@ bool QmlPropertyNode::fromTrool(Trool troolean, bool defaultValue)
return defaultValue;
}
}
+
+static QString valueType(const QString& n)
+{
+ if (n == "QPoint")
+ return "QDeclarativePointValueType";
+ if (n == "QPointF")
+ return "QDeclarativePointFValueType";
+ if (n == "QSize")
+ return "QDeclarativeSizeValueType";
+ if (n == "QSizeF")
+ return "QDeclarativeSizeFValueType";
+ if (n == "QRect")
+ return "QDeclarativeRectValueType";
+ if (n == "QRectF")
+ return "QDeclarativeRectFValueType";
+ if (n == "QVector2D")
+ return "QDeclarativeVector2DValueType";
+ if (n == "QVector3D")
+ return "QDeclarativeVector3DValueType";
+ if (n == "QVector4D")
+ return "QDeclarativeVector4DValueType";
+ if (n == "QQuaternion")
+ return "QDeclarativeQuaternionValueType";
+ if (n == "QMatrix4x4")
+ return "QDeclarativeMatrix4x4ValueType";
+ if (n == "QEasingCurve")
+ return "QDeclarativeEasingValueType";
+ if (n == "QFont")
+ return "QDeclarativeFontValueType";
+ return QString();
+}
+
+/*!
+ Returns true if a QML property or attached property is
+ read-only. The algorithm for figuring this out is long
+ amd tedious and almost certainly will break. It currently
+ doesn't work for qmlproperty bool PropertyChanges::explicit,
+ because the tokenized gets confused on "explicit" .
+ */
+bool QmlPropertyNode::isWritable(const Tree* tree) const
+{
+ Node* n = parent();
+ while (n && n->subType() != Node::QmlClass)
+ n = n->parent();
+ if (n) {
+ const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
+ const ClassNode* cn = qcn->classNode();
+ if (cn) {
+ QStringList dotSplit = name().split(QChar('.'));
+ const PropertyNode* pn = cn->findPropertyNode(dotSplit[0]);
+ if (pn) {
+ if (dotSplit.size() > 1) {
+ QStringList path(extractClassName(pn->qualifiedDataType()));
+ const Node* nn = tree->findNode(path,Class);
+ if (nn) {
+ const ClassNode* cn = static_cast<const ClassNode*>(nn);
+ pn = cn->findPropertyNode(dotSplit[1]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ else {
+ const QList<RelatedClass>& bases = cn->baseClasses();
+ if (!bases.isEmpty()) {
+ for (int i=0; i<bases.size(); ++i) {
+ const ClassNode* cn = bases[i].node;
+ pn = cn->findPropertyNode(dotSplit[1]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ }
+ }
+ const QList<RelatedClass>& ignoredBases = cn->ignoredBaseClasses();
+ if (!ignoredBases.isEmpty()) {
+ for (int i=0; i<ignoredBases.size(); ++i) {
+ const ClassNode* cn = ignoredBases[i].node;
+ pn = cn->findPropertyNode(dotSplit[1]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ }
+ }
+ QString vt = valueType(cn->name());
+ if (!vt.isEmpty()) {
+ QStringList path(vt);
+ const Node* vtn = tree->findNode(path,Class);
+ if (vtn) {
+ const ClassNode* cn = static_cast<const ClassNode*>(vtn);
+ pn = cn->findPropertyNode(dotSplit[1]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ return pn->isWritable();
+ }
+ }
+ else {
+ const QList<RelatedClass>& bases = cn->baseClasses();
+ if (!bases.isEmpty()) {
+ for (int i=0; i<bases.size(); ++i) {
+ const ClassNode* cn = bases[i].node;
+ pn = cn->findPropertyNode(dotSplit[0]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ }
+ }
+ const QList<RelatedClass>& ignoredBases = cn->ignoredBaseClasses();
+ if (!ignoredBases.isEmpty()) {
+ for (int i=0; i<ignoredBases.size(); ++i) {
+ const ClassNode* cn = ignoredBases[i].node;
+ pn = cn->findPropertyNode(dotSplit[0]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ }
+ }
+ if (isAttached()) {
+ QString classNameAttached = cn->name() + "Attached";
+ QStringList path(classNameAttached);
+ const Node* nn = tree->findNode(path,Class);
+ const ClassNode* acn = static_cast<const ClassNode*>(nn);
+ pn = acn->findPropertyNode(dotSplit[0]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ }
+ }
+ }
+ }
+ location().warning(tr("Can't determine read-only status of QML property %1; writable assumed.").arg(name()));
+ return true;
+}
+
#endif
QT_END_NAMESPACE
diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h
index 121b818..40b78ef 100644
--- a/tools/qdoc3/node.h
+++ b/tools/qdoc3/node.h
@@ -193,6 +193,7 @@ class Node
virtual QString fileBase() const;
QUuid guid() const;
QString ditaXmlHref();
+ QString extractClassName(const QString &string) const;
protected:
Node(Type type, InnerNode* parent, const QString& name);
@@ -326,6 +327,8 @@ struct RelatedClass
QString dataTypeWithTemplateArgs;
};
+class PropertyNode;
+
class ClassNode : public InnerNode
{
public:
@@ -337,8 +340,9 @@ class ClassNode : public InnerNode
const QString &dataTypeWithTemplateArgs = "");
void fixBaseClasses();
- const QList<RelatedClass> &baseClasses() const { return bas; }
- const QList<RelatedClass> &derivedClasses() const { return der; }
+ const QList<RelatedClass> &baseClasses() const { return bases; }
+ const QList<RelatedClass> &derivedClasses() const { return derived; }
+ const QList<RelatedClass> &ignoredBaseClasses() const { return ignoredBases; }
bool hideFromMainList() const { return hidden; }
void setHideFromMainList(bool value) { hidden = value; }
@@ -349,10 +353,12 @@ class ClassNode : public InnerNode
void setQmlElement(const QString& value) { qmlelement = value; }
virtual bool isAbstract() const { return abstract; }
virtual void setAbstract(bool b) { abstract = b; }
+ const PropertyNode* findPropertyNode(const QString& name) const;
private:
- QList<RelatedClass> bas;
- QList<RelatedClass> der;
+ QList<RelatedClass> bases;
+ QList<RelatedClass> derived;
+ QList<RelatedClass> ignoredBases;
bool hidden;
bool abstract;
QString sname;
@@ -436,6 +442,8 @@ class QmlPropGroupNode : public FakeNode
bool att;
};
+class Tree;
+
class QmlPropertyNode : public LeafNode
{
public:
@@ -454,7 +462,7 @@ class QmlPropertyNode : public LeafNode
QString qualifiedDataType() const { return dt; }
bool isStored() const { return fromTrool(sto,true); }
bool isDesignable() const { return fromTrool(des,false); }
- bool isWritable() const { return fromTrool(wri,true); }
+ bool isWritable(const Tree* tree) const;
bool isAttached() const { return att; }
virtual bool isQmlNode() const { return true; }
diff --git a/tools/qdoc3/test/qt-cpp-ignore.qdocconf b/tools/qdoc3/test/qt-cpp-ignore.qdocconf
index 8cc4fd9..4963b96 100644
--- a/tools/qdoc3/test/qt-cpp-ignore.qdocconf
+++ b/tools/qdoc3/test/qt-cpp-ignore.qdocconf
@@ -91,4 +91,6 @@ Cpp.ignoredirectives = Q_DECLARE_HANDLE \
K_DECLARE_PRIVATE \
PHONON_OBJECT \
PHONON_HEIR \
- Q_PRIVATE_PROPERTY
+ Q_PRIVATE_PROPERTY \
+ Q_DECLARE_PRIVATE_D \
+ Q_CLASSINFO
diff --git a/tools/qdoc3/tokenizer.cpp b/tools/qdoc3/tokenizer.cpp
index 7c10de6..05ad5ee 100644
--- a/tools/qdoc3/tokenizer.cpp
+++ b/tools/qdoc3/tokenizer.cpp
@@ -67,7 +67,11 @@ static const char *kwords[] = {
"private", "protected", "public", "short", "signals", "signed",
"slots", "static", "struct", "template", "typedef", "typename",
"union", "unsigned", "using", "virtual", "void", "volatile",
- "__int64", "Q_OBJECT", "Q_OVERRIDE", "Q_PROPERTY",
+ "__int64",
+ "Q_OBJECT",
+ "Q_OVERRIDE",
+ "Q_PROPERTY",
+ "Q_PRIVATE_PROPERTY",
"Q_DECLARE_SEQUENTIAL_ITERATOR",
"Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR",
"Q_DECLARE_ASSOCIATIVE_ITERATOR",
diff --git a/tools/qdoc3/tokenizer.h b/tools/qdoc3/tokenizer.h
index f55d2ef..bd35965 100644
--- a/tools/qdoc3/tokenizer.h
+++ b/tools/qdoc3/tokenizer.h
@@ -75,7 +75,7 @@ enum { Tok_Eoi, Tok_Ampersand, Tok_Aster, Tok_Caret, Tok_LeftParen,
Tok_static, Tok_struct, Tok_template, Tok_typedef,
Tok_typename, Tok_union, Tok_unsigned, Tok_using, Tok_virtual,
Tok_void, Tok_volatile, Tok_int64, Tok_Q_OBJECT, Tok_Q_OVERRIDE,
- Tok_Q_PROPERTY, Tok_Q_DECLARE_SEQUENTIAL_ITERATOR,
+ Tok_Q_PROPERTY, Tok_Q_PRIVATE_PROPERTY, Tok_Q_DECLARE_SEQUENTIAL_ITERATOR,
Tok_Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR,
Tok_Q_DECLARE_ASSOCIATIVE_ITERATOR,
Tok_Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR,
diff --git a/tools/qdoc3/tree.cpp b/tools/qdoc3/tree.cpp
index d22a09a..56e3484 100644
--- a/tools/qdoc3/tree.cpp
+++ b/tools/qdoc3/tree.cpp
@@ -469,8 +469,9 @@ void Tree::resolveInheritance(NamespaceNode *rootNode)
for (int pass = 0; pass < 2; pass++) {
NodeList::ConstIterator c = rootNode->childNodes().begin();
while (c != rootNode->childNodes().end()) {
- if ((*c)->type() == Node::Class)
+ if ((*c)->type() == Node::Class) {
resolveInheritance(pass, (ClassNode *) *c);
+ }
else if ((*c)->type() == Node::Namespace) {
NamespaceNode *ns = static_cast<NamespaceNode*>(*c);
resolveInheritance(ns);
@@ -542,14 +543,16 @@ void Tree::resolveInheritance(int pass, ClassNode *classe)
while (b != bounds.end()) {
ClassNode *baseClass = (ClassNode*)findNode((*b).basePath,
Node::Class);
- if (!baseClass && (*b).parent)
+ if (!baseClass && (*b).parent) {
baseClass = (ClassNode*)findNode((*b).basePath,
Node::Class,
(*b).parent);
- if (baseClass)
+ }
+ if (baseClass) {
classe->addBaseClass((*b).access,
baseClass,
(*b).dataTypeWithTemplateArgs);
+ }
++b;
}
}