diff options
author | Martin Smith <martin.smith@qt.io> | 2017-01-17 11:44:41 +0100 |
---|---|---|
committer | Martin Smith <martin.smith@qt.io> | 2017-08-10 07:33:53 +0000 |
commit | 816b967374aa714139ddc59676dd32702bed9f49 (patch) | |
tree | e7e664d94acb2fcbe55d405df6fdc8e761db6d56 | |
parent | 54425fbd3de2911bf98a934423ec22e495e8424c (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.cpp | 16 | ||||
-rw-r--r-- | src/qdoc/cppcodeparser.cpp | 2 | ||||
-rw-r--r-- | src/qdoc/cppcodeparser.h | 1 | ||||
-rw-r--r-- | src/qdoc/node.cpp | 272 | ||||
-rw-r--r-- | src/qdoc/node.h | 15 |
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; |