summaryrefslogtreecommitdiff
path: root/src/qdoc/clangcodeparser.cpp
diff options
context:
space:
mode:
authorTopi Reinio <topi.reinio@qt.io>2020-08-11 11:18:26 +0200
committerTopi Reinio <topi.reinio@qt.io>2020-09-21 12:43:04 +0200
commit5b11b631914ff399d72f0a9b58a7b06e96fc7a6a (patch)
tree6d911b0ea8f19c02b5d7e39f752ef79352c1cc00 /src/qdoc/clangcodeparser.cpp
parent6e88d94fc5ec05fc5fe2401d91329b096cb801aa (diff)
downloadqttools-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.cpp52
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;
}
/*!