summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Smith <martin.smith@qt.io>2017-01-17 11:44:41 +0100
committerMartin Smith <martin.smith@qt.io>2017-08-10 07:33:53 +0000
commit816b967374aa714139ddc59676dd32702bed9f49 (patch)
treee7e664d94acb2fcbe55d405df6fdc8e761db6d56
parent54425fbd3de2911bf98a934423ec22e495e8424c (diff)
qdoc: Enable documentation of type alias as typedef
clangqdoc now handles the type alias declaraction and provides the \typealias command for documenting it. It is documented as a typedef. Task-number: QTBUG-58158 Change-Id: Iee0c8dea66026a89b3625b40b92b056cada893c1 Reviewed-by: Topi Reiniƶ <topi.reinio@qt.io>
-rw-r--r--src/qdoc/clangcodeparser.cpp16
-rw-r--r--src/qdoc/cppcodeparser.cpp2
-rw-r--r--src/qdoc/cppcodeparser.h1
-rw-r--r--src/qdoc/node.cpp272
-rw-r--r--src/qdoc/node.h15
5 files changed, 48 insertions, 258 deletions
diff --git a/src/qdoc/clangcodeparser.cpp b/src/qdoc/clangcodeparser.cpp
index c7bb37120..db3461c7f 100644
--- a/src/qdoc/clangcodeparser.cpp
+++ b/src/qdoc/clangcodeparser.cpp
@@ -378,6 +378,22 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l
{
auto kind = clang_getCursorKind(cursor);
switch (kind) {
+ case CXCursor_TypeAliasDecl: {
+ QString spelling = getSpelling(clang_getCursorExtent(cursor));
+ QStringList typeAlias = spelling.split(QChar('='));
+ if (typeAlias.size() == 2) {
+ typeAlias[0] = typeAlias[0].trimmed();
+ typeAlias[1] = typeAlias[1].trimmed();
+ int lastBlank = typeAlias[0].lastIndexOf(QChar(' '));
+ if (lastBlank > 0) {
+ typeAlias[0] = typeAlias[0].right(typeAlias[0].size() - (lastBlank + 1));
+ TypeAliasNode* ta = new TypeAliasNode(parent_, typeAlias[0], typeAlias[1]);
+ ta->setAccess(fromCX_CXXAccessSpecifier(clang_getCXXAccessSpecifier(cursor)));
+ ta->setLocation(fromCXSourceLocation(clang_getCursorLocation(cursor)));
+ }
+ }
+ return CXChildVisit_Continue;
+ }
case CXCursor_StructDecl:
case CXCursor_UnionDecl:
case CXCursor_ClassDecl:
diff --git a/src/qdoc/cppcodeparser.cpp b/src/qdoc/cppcodeparser.cpp
index 798b6e395..d22cdffbb 100644
--- a/src/qdoc/cppcodeparser.cpp
+++ b/src/qdoc/cppcodeparser.cpp
@@ -86,6 +86,7 @@ void CppCodeParser::initializeParser(const Config &config)
nodeTypeMap.insert(COMMAND_NAMESPACE, Node::Namespace);
nodeTypeMap.insert(COMMAND_CLASS, Node::Class);
nodeTypeMap.insert(COMMAND_ENUM, Node::Enum);
+ nodeTypeMap.insert(COMMAND_TYPEALIAS, Node::Typedef);
nodeTypeMap.insert(COMMAND_TYPEDEF, Node::Typedef);
nodeTypeMap.insert(COMMAND_PROPERTY, Node::Property);
nodeTypeMap.insert(COMMAND_VARIABLE, Node::Variable);
@@ -172,6 +173,7 @@ const QSet<QString>& CppCodeParser::topicCommands()
<< COMMAND_NAMESPACE
<< COMMAND_PAGE
<< COMMAND_PROPERTY
+ << COMMAND_TYPEALIAS
<< COMMAND_TYPEDEF
<< COMMAND_VARIABLE
<< COMMAND_QMLTYPE
diff --git a/src/qdoc/cppcodeparser.h b/src/qdoc/cppcodeparser.h
index 79e5f47b6..8d217e3fe 100644
--- a/src/qdoc/cppcodeparser.h
+++ b/src/qdoc/cppcodeparser.h
@@ -177,6 +177,7 @@ protected:
#define COMMAND_REIMP Doc::alias("reimp")
#define COMMAND_RELATES Doc::alias("relates")
#define COMMAND_STARTPAGE Doc::alias("startpage")
+#define COMMAND_TYPEALIAS Doc::alias("typealias")
#define COMMAND_TYPEDEF Doc::alias("typedef")
#define COMMAND_VARIABLE Doc::alias("variable")
#define COMMAND_QMLABSTRACT Doc::alias("qmlabstract")
diff --git a/src/qdoc/node.cpp b/src/qdoc/node.cpp
index ce86661cf..4469cd604 100644
--- a/src/qdoc/node.cpp
+++ b/src/qdoc/node.cpp
@@ -70,6 +70,7 @@ void Node::initialize()
goals_.insert("qmlmethod", Node::QmlMethod);
goals_.insert("qmlbasictype", Node::QmlBasicType);
goals_.insert("enum", Node::Enum);
+ goals_.insert("typealias", Node::Typedef);
goals_.insert("typedef", Node::Typedef);
goals_.insert("namespace", Node::Namespace);
}
@@ -700,33 +701,6 @@ Node::ThreadSafeness Node::inheritedThreadSafeness() const
return (ThreadSafeness) safeness_;
}
-#if 0
-/*!
- Returns the sanitized file name without the path.
- If the file is an html file, the html suffix
- is removed. Why?
- */
-QString Node::fileBase() const
-{
- QString base = name();
- if (base.endsWith(".html"))
- base.chop(5);
- base.replace(QRegExp("[^A-Za-z0-9]+"), " ");
- base = base.trimmed();
- base.replace(QLatin1Char(' '), QLatin1Char('-'));
- return base.toLower();
-}
-/*!
- Returns this node's Universally Unique IDentifier as a
- QString. Creates the UUID first, if it has not been created.
- */
-QString Node::guid() const
-{
- if (uuid_.isEmpty())
- uuid_ = idForNode();
- return uuid_;
-}
-#endif
/*!
If this node is a QML or JS type node, return a pointer to
@@ -1956,6 +1930,20 @@ void TypedefNode::setAssociatedEnum(const EnumNode *enume)
}
/*!
+ \class TypeAliasNode
+ */
+
+/*!
+ Constructs a TypeAliasNode for the \a aliasedType with the
+ specified \a name and \a parent.
+ */
+TypeAliasNode::TypeAliasNode(Aggregate *parent, const QString& name, const QString& aliasedType)
+ : TypedefNode(parent, name), aliasedType_(aliasedType)
+{
+ // nothing.
+}
+
+/*!
\class Parameter
\brief The class Parameter contains one parameter.
@@ -2842,236 +2830,6 @@ QString Node::cleanId(const QString &str)
return clean;
}
-#if 0
-/*!
- Creates a string that can be used as a UUID for the node,
- depending on the type and subtype of the node. Uniquenss
- is not guaranteed, but it is expected that strings created
- here will be unique within an XML document. Hence, the
- returned string can be used as the value of an \e id
- attribute.
- */
-QString Node::idForNode() const
-{
- const FunctionNode* func;
- const TypedefNode* tdn;
- QString str;
-
- switch (type()) {
- case Node::Namespace:
- str = "namespace-" + fullDocumentName();
- break;
- case Node::Class:
- str = "class-" + fullDocumentName();
- break;
- case Node::Enum:
- str = "enum-" + name();
- break;
- case Node::Typedef:
- tdn = static_cast<const TypedefNode*>(this);
- if (tdn->associatedEnum()) {
- return tdn->associatedEnum()->idForNode();
- }
- else {
- str = "typedef-" + name();
- }
- break;
- case Node::Function:
- func = static_cast<const FunctionNode*>(this);
- if (func->associatedProperty()) {
- return func->associatedProperty()->idForNode();
- }
- else {
- if (func->name().startsWith("operator")) {
- str.clear();
- /*
- The test below should probably apply to all
- functions, but for now, overloaded operators
- are the only ones that produce duplicate id
- attributes in the DITA XML files.
- */
- if (relatesTo_)
- str = "nonmember-";
- QString op = func->name().mid(8);
- if (!op.isEmpty()) {
- int i = 0;
- while (i<op.size() && op.at(i) == ' ')
- ++i;
- if (i>0 && i<op.size()) {
- op = op.mid(i);
- }
- if (!op.isEmpty()) {
- i = 0;
- while (i < op.size()) {
- const QChar c = op.at(i);
- const uint u = c.unicode();
- if ((u >= 'a' && u <= 'z') ||
- (u >= 'A' && u <= 'Z') ||
- (u >= '0' && u <= '9'))
- break;
- ++i;
- }
- str += "operator-";
- if (i>0) {
- QString tail = op.mid(i);
- op = op.left(i);
- if (operators_.contains(op)) {
- str += operators_.value(op);
- if (!tail.isEmpty())
- str += QLatin1Char('-') + tail;
- }
- else
- qDebug() << "qdoc internal error: Operator missing from operators_ map:" << op;
- }
- else {
- str += op;
- }
- }
- }
- }
- else if (parent_) {
- if (parent_->isClass())
- str = "class-member-" + func->name();
- else if (parent_->isNamespace())
- str = "namespace-member-" + func->name();
- else if (parent_->isQmlType())
- str = "qml-method-" + parent_->name().toLower() + "-" + func->name();
- else if (parent_->isJsType())
- str = "js-method-" + parent_->name().toLower() + "-" + func->name();
- else if (parent_->type() == Document) {
- qDebug() << "qdoc internal error: Node subtype not handled:"
- << parent_->docSubtype() << func->name();
- }
- else
- qDebug() << "qdoc internal error: Node type not handled:"
- << parent_->type() << func->name();
-
- }
- if (func->overloadNumber() != 0)
- str += QLatin1Char('-') + QString::number(func->overloadNumber());
- }
- break;
- case Node::QmlType:
- if (genus() == QML)
- str = "qml-class-" + name();
- else
- str = "js-type-" + name();
- break;
- case Node::QmlBasicType:
- if (genus() == QML)
- str = "qml-basic-type-" + name();
- else
- str = "js-basic-type-" + name();
- break;
- case Node::Document:
- {
- switch (docSubtype()) {
- case Node::Page:
- case Node::HeaderFile:
- str = title();
- if (str.isEmpty()) {
- str = name();
- if (str.endsWith(".html"))
- str.remove(str.size()-5,5);
- }
- str.replace(QLatin1Char('/'), QLatin1Char('-'));
- break;
- case Node::File:
- str = name();
- str.replace(QLatin1Char('/'), QLatin1Char('-'));
- break;
- case Node::Example:
- str = name();
- str.replace(QLatin1Char('/'), QLatin1Char('-'));
- break;
- default:
- qDebug() << "ERROR: A case was not handled in Node::idForNode():"
- << "docSubtype():" << docSubtype() << "type():" << type();
- break;
- }
- }
- break;
- case Node::Group:
- case Node::Module:
- str = title();
- if (str.isEmpty()) {
- str = name();
- if (str.endsWith(".html"))
- str.remove(str.size()-5,5);
- }
- str.replace(QLatin1Char('/'), QLatin1Char('-'));
- break;
- case Node::QmlModule:
- if (genus() == QML)
- str = "qml-module-" + name();
- else
- str = "js-module-" + name();
- break;
- case Node::QmlProperty:
- if (genus() == QML)
- str = "qml-";
- else
- str = "js-";
- if (isAttached())
- str += "attached-property-" + name();
- else
- str += "property-" + name();
- break;
- case Node::QmlPropertyGroup:
- {
- Node* n = const_cast<Node*>(this);
- if (genus() == QML)
- str = "qml-propertygroup-" + n->name();
- else
- str = "js-propertygroup-" + n->name();
- }
- break;
- case Node::Property:
- str = "property-" + name();
- break;
- case Node::QmlSignal:
- if (genus() == QML)
- str = "qml-signal-" + name();
- else
- str = "js-signal-" + name();
- break;
- case Node::QmlSignalHandler:
- if (genus() == QML)
- str = "qml-signal-handler-" + name();
- else
- str = "js-signal-handler-" + name();
- break;
- case Node::QmlMethod:
- func = static_cast<const FunctionNode*>(this);
- if (genus() == QML)
- str = "qml-method-";
- else
- str = "js-method-";
- str += parent_->name().toLower() + "-" + func->name();
- if (func->overloadNumber() != 0)
- str += QLatin1Char('-') + QString::number(func->overloadNumber());
- break;
- case Node::Variable:
- str = "var-" + name();
- break;
- default:
- qDebug() << "ERROR: A case was not handled in Node::idForNode():"
- << "type():" << type() << "docSubtype():" << docSubtype();
- break;
- }
- if (str.isEmpty()) {
- qDebug() << "ERROR: A link text was empty in Node::idForNode():"
- << "type():" << type() << "docSubtype():" << docSubtype()
- << "name():" << name()
- << "title():" << title();
- }
- else {
- str = cleanId(str);
- }
- return str;
-}
-#endif
-
/*!
Prints the inner node's list of children.
For debugging only.
diff --git a/src/qdoc/node.h b/src/qdoc/node.h
index f5507293c..fe46b7d18 100644
--- a/src/qdoc/node.h
+++ b/src/qdoc/node.h
@@ -205,6 +205,7 @@ public:
virtual bool isJsBasicType() const { return false; }
virtual bool isEnumType() const { return false; }
virtual bool isTypedef() const { return false; }
+ virtual bool isTypeAlias() const { return false; }
virtual bool isExample() const { return false; }
virtual bool isExampleFile() const { return false; }
virtual bool isHeaderFile() const { return false; }
@@ -322,7 +323,6 @@ public:
virtual void setOutputSubdirectory(const QString& t) { outSubDir_ = t; }
QString fullDocumentName() const;
static QString cleanId(const QString &str);
- //QString idForNode() const;
static FlagValue toFlagValue(bool b);
static bool fromFlagValue(FlagValue fv, bool defaultValue);
@@ -824,6 +824,19 @@ private:
const EnumNode* associatedEnum_;
};
+class TypeAliasNode : public TypedefNode
+{
+ public:
+ TypeAliasNode(Aggregate* parent, const QString& name, const QString& aliasedType);
+ virtual ~TypeAliasNode() { }
+
+ virtual bool isTypeAlias() const { return true; }
+ QString aliasedType() { return aliasedType_; }
+
+ private:
+ QString aliasedType_;
+};
+
inline void EnumNode::setFlagsType(TypedefNode* t)
{
flagsType_ = t;