diff options
author | Topi Reinio <topi.reinio@qt.io> | 2020-08-11 11:18:26 +0200 |
---|---|---|
committer | Topi Reinio <topi.reinio@qt.io> | 2020-09-21 12:43:04 +0200 |
commit | 5b11b631914ff399d72f0a9b58a7b06e96fc7a6a (patch) | |
tree | 6d911b0ea8f19c02b5d7e39f752ef79352c1cc00 /src/qdoc/clangcodeparser.cpp | |
parent | 6e88d94fc5ec05fc5fe2401d91329b096cb801aa (diff) | |
download | qttools-5b11b631914ff399d72f0a9b58a7b06e96fc7a6a.tar.gz |
qdoc: Add support for bindable properties
Add support for the BINDABLE attribute in the Q_PROPERTY macro.
The new properties are marked with 'bindable' tag, and the list
of access functions/notifier signal is replaced with a descriptive
note and a link to QProperty. Read-only properties are also
properly marked as such.
[ChangeLog][qdoc] The \property command now supports bindable C++
properties that use the new system based on QProperty.
Task-number: QTBUG-85565
Change-Id: Ie352b3ce962b6b05a022d444da0991b8a849e474
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Reviewed-by: Paul Wicking <paul.wicking@qt.io>
Diffstat (limited to 'src/qdoc/clangcodeparser.cpp')
-rw-r--r-- | src/qdoc/clangcodeparser.cpp | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/src/qdoc/clangcodeparser.cpp b/src/qdoc/clangcodeparser.cpp index 9f9dba7e0..36a65c1f1 100644 --- a/src/qdoc/clangcodeparser.cpp +++ b/src/qdoc/clangcodeparser.cpp @@ -468,6 +468,9 @@ private: { if (symbolName == QLatin1String("QPrivateSignal")) return true; + // Ignore functions generated by property macros + if (symbolName.startsWith("_qt_property_")) + return true; return false; } @@ -500,7 +503,7 @@ private: CXChildVisitResult visitHeader(CXCursor cursor, CXSourceLocation loc); CXChildVisitResult visitFnSignature(CXCursor cursor, CXSourceLocation loc, Node **fnNode, bool &ignoreSignature); - void parseProperty(const QString &spelling, const Location &loc); + bool parseProperty(const QString &spelling, const Location &loc); void readParameterNamesAndAttributes(FunctionNode *fn, CXCursor cursor); Aggregate *getSemanticParent(CXCursor cursor); }; @@ -609,8 +612,7 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l if (!clang_isCursorDefinition(cursor)) return CXChildVisit_Continue; - if (findNodeForCursor(qdb_, - cursor)) // Was already parsed, propably in another translation unit + if (findNodeForCursor(qdb_, cursor)) // Was already parsed, probably in another TU return CXChildVisit_Continue; QString className = fromCXString(clang_getCursorSpelling(cursor)); @@ -679,8 +681,7 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l case CXCursor_Constructor: case CXCursor_Destructor: case CXCursor_ConversionFunction: { - if (findNodeForCursor(qdb_, - cursor)) // Was already parsed, propably in another translation unit + if (findNodeForCursor(qdb_, cursor)) // Was already parsed, probably in another TU return CXChildVisit_Continue; QString name = functionName(cursor); if (ignoredSymbol(name)) @@ -838,9 +839,9 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l } case CXCursor_FieldDecl: case CXCursor_VarDecl: { - if (findNodeForCursor(qdb_, - cursor)) // Was already parsed, propably in another translation unit + if (findNodeForCursor(qdb_, cursor)) // Was already parsed, probably in another TU return CXChildVisit_Continue; + auto access = fromCX_CXXAccessSpecifier(clang_getCXXAccessSpecifier(cursor)); auto var = new VariableNode(parent_, fromCXString(clang_getCursorSpelling(cursor))); var->setAccess(access); @@ -850,8 +851,7 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l return CXChildVisit_Continue; } case CXCursor_TypedefDecl: { - if (findNodeForCursor(qdb_, - cursor)) // Was already parsed, propably in another translation unit + if (findNodeForCursor(qdb_, cursor)) // Was already parsed, probably in another TU return CXChildVisit_Continue; TypedefNode *td = new TypedefNode(parent_, fromCXString(clang_getCursorSpelling(cursor))); td->setAccess(fromCX_CXXAccessSpecifier(clang_getCXXAccessSpecifier(cursor))); @@ -877,13 +877,10 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l } default: if (clang_isDeclaration(kind) && parent_->isClassNode()) { - // maybe a static_assert (which is not exposed from the clang API) - QString spelling = getSpelling(clang_getCursorExtent(cursor)); - if (spelling.startsWith(QLatin1String("Q_PROPERTY")) - || spelling.startsWith(QLatin1String("QDOC_PROPERTY")) - || spelling.startsWith(QLatin1String("Q_OVERRIDE"))) { - parseProperty(spelling, fromCXSourceLocation(loc)); - } + // may be a property macro or a static_assert + // which is not exposed from the clang API + parseProperty(getSpelling(clang_getCursorExtent(cursor)), + fromCXSourceLocation(loc)); } return CXChildVisit_Continue; } @@ -933,22 +930,31 @@ void ClangVisitor::readParameterNamesAndAttributes(FunctionNode *fn, CXCursor cu }); } -void ClangVisitor::parseProperty(const QString &spelling, const Location &loc) +bool ClangVisitor::parseProperty(const QString &spelling, const Location &loc) { + if (!spelling.startsWith(QLatin1String("Q_PROPERTY")) + && !spelling.startsWith(QLatin1String("QDOC_PROPERTY")) + && !spelling.startsWith(QLatin1String("Q_OVERRIDE"))) + return false; + int lpIdx = spelling.indexOf(QChar('(')); int rpIdx = spelling.lastIndexOf(QChar(')')); if (lpIdx <= 0 || rpIdx <= lpIdx) - return; + return false; + QString signature = spelling.mid(lpIdx + 1, rpIdx - lpIdx - 1); signature = signature.simplified(); - QStringList part = signature.split(QChar(' ')); + + QStringList part; + part = signature.split(QChar(' ')); if (part.first() == QLatin1String("enum")) part.takeFirst(); // QTBUG-80027 if (part.size() < 2) - return; + return false; QString type = part.at(0); QString name = part.at(1); - if (name.at(0) == QChar('*')) { + + if (name.front() == QChar('*')) { type.append(QChar('*')); name.remove(0, 1); } @@ -956,6 +962,7 @@ void ClangVisitor::parseProperty(const QString &spelling, const Location &loc) property->setAccess(Access::Public); property->setLocation(loc); property->setDataType(type); + int i = 2; while (i < part.size()) { QString key = part.at(i++); @@ -986,6 +993,8 @@ void ClangVisitor::parseProperty(const QString &spelling, const Location &loc) property->setDesignable(false); property->setRuntimeDesFunc(value); } + } else if (key == "BINDABLE") { + property->setPropertyType(PropertyNode::Bindable); } else if (key == "RESET") { qdb_->addPropertyFunction(property, value, PropertyNode::Resetter); } else if (key == "NOTIFY") { @@ -1011,6 +1020,7 @@ void ClangVisitor::parseProperty(const QString &spelling, const Location &loc) } } } + return true; } /*! |