aboutsummaryrefslogtreecommitdiffstats
path: root/src/QtUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/QtUtils.cpp')
-rw-r--r--src/QtUtils.cpp109
1 files changed, 64 insertions, 45 deletions
diff --git a/src/QtUtils.cpp b/src/QtUtils.cpp
index 8a72392b..05f463d2 100644
--- a/src/QtUtils.cpp
+++ b/src/QtUtils.cpp
@@ -34,7 +34,7 @@
using namespace std;
using namespace clang;
-bool QtUtils::isQtIterableClass(clang::CXXRecordDecl *record)
+bool clazy::isQtIterableClass(clang::CXXRecordDecl *record)
{
if (!record)
return false;
@@ -42,30 +42,41 @@ bool QtUtils::isQtIterableClass(clang::CXXRecordDecl *record)
return isQtIterableClass(record->getQualifiedNameAsString());
}
-const vector<string> & QtUtils::qtContainers()
+const vector<StringRef> & clazy::qtContainers()
{
- static const vector<string> classes = { "QListSpecialMethods", "QList", "QVector", "QVarLengthArray", "QMap",
- "QHash", "QMultiMap", "QMultiHash", "QSet", "QStack", "QQueue", "QString", "QStringRef",
- "QByteArray", "QSequentialIterable", "QAssociativeIterable", "QJsonArray", "QLinkedList" };
+ static const vector<StringRef> classes = { "QListSpecialMethods", "QList", "QVector", "QVarLengthArray", "QMap",
+ "QHash", "QMultiMap", "QMultiHash", "QSet", "QStack", "QQueue", "QString", "QStringRef",
+ "QByteArray", "QSequentialIterable", "QAssociativeIterable", "QJsonArray", "QLinkedList" };
return classes;
}
-const vector<string> & QtUtils::qtCOWContainers()
+const vector<StringRef> & clazy::qtCOWContainers()
{
- static const vector<string> classes = { "QListSpecialMethods", "QList", "QVector", "QMap", "QHash",
- "QMultiMap", "QMultiHash", "QSet", "QStack", "QQueue", "QString", "QStringRef",
- "QByteArray", "QJsonArray", "QLinkedList" };
+ static const vector<StringRef> classes = { "QListSpecialMethods", "QList", "QVector", "QMap", "QHash",
+ "QMultiMap", "QMultiHash", "QSet", "QStack", "QQueue", "QString", "QStringRef",
+ "QByteArray", "QJsonArray", "QLinkedList" };
return classes;
}
-std::unordered_map<string, std::vector<string> > QtUtils::detachingMethods()
+std::unordered_map<string, std::vector<StringRef> > clazy::detachingMethods()
{
- static std::unordered_map<string, std::vector<string> > map;
+ static std::unordered_map<string, std::vector<StringRef> > map;
+ if (map.empty()) {
+ map = detachingMethodsWithConstCounterParts();
+ map["QVector"].push_back("fill");
+ }
+
+ return map;
+}
+
+std::unordered_map<string, std::vector<StringRef> > clazy::detachingMethodsWithConstCounterParts()
+{
+ static std::unordered_map<string, std::vector<StringRef> > map;
if (map.empty()) {
map["QList"] = {"first", "last", "begin", "end", "front", "back", "operator[]"};
- map["QVector"] = {"first", "last", "begin", "end", "front", "back", "data", "operator[]", "fill" };
- map["QMap"] = {"begin", "end", "first", "find", "last", "lowerBound", "upperBound", "operator[]" };
+ map["QVector"] = {"first", "last", "begin", "end", "front", "back", "data", "operator[]" };
+ map["QMap"] = {"begin", "end", "first", "find", "last", "operator[]", "lowerBound", "upperBound" };
map["QHash"] = {"begin", "end", "find", "operator[]" };
map["QLinkedList"] = {"first", "last", "begin", "end", "front", "back", "operator[]" };
map["QSet"] = {"begin", "end", "find", "operator[]" };
@@ -83,8 +94,7 @@ std::unordered_map<string, std::vector<string> > QtUtils::detachingMethods()
return map;
}
-
-bool QtUtils::isQtCOWIterableClass(clang::CXXRecordDecl *record)
+bool clazy::isQtCOWIterableClass(clang::CXXRecordDecl *record)
{
if (!record)
return false;
@@ -92,19 +102,19 @@ bool QtUtils::isQtCOWIterableClass(clang::CXXRecordDecl *record)
return isQtCOWIterableClass(record->getQualifiedNameAsString());
}
-bool QtUtils::isQtCOWIterableClass(const string &className)
+bool clazy::isQtCOWIterableClass(const string &className)
{
const auto &classes = qtCOWContainers();
- return clazy_std::contains(classes, className);
+ return clazy::contains(classes, className);
}
-bool QtUtils::isQtIterableClass(const string &className)
+bool clazy::isQtIterableClass(StringRef className)
{
const auto &classes = qtContainers();
- return clazy_std::contains(classes, className);
+ return clazy::contains(classes, className);
}
-bool QtUtils::isQtAssociativeContainer(clang::CXXRecordDecl *record)
+bool clazy::isQtAssociativeContainer(clang::CXXRecordDecl *record)
{
if (!record)
return false;
@@ -112,25 +122,25 @@ bool QtUtils::isQtAssociativeContainer(clang::CXXRecordDecl *record)
return isQtAssociativeContainer(record->getNameAsString());
}
-bool QtUtils::isQtAssociativeContainer(const string &className)
+bool clazy::isQtAssociativeContainer(StringRef className)
{
- static const vector<string> classes = { "QSet", "QMap", "QHash" };
- return clazy_std::contains(classes, className);
+ static const vector<StringRef> classes = { "QSet", "QMap", "QHash" };
+ return clazy::contains(classes, className);
}
-bool QtUtils::isQObject(CXXRecordDecl *decl)
+bool clazy::isQObject(const CXXRecordDecl *decl)
{
return TypeUtils::derivesFrom(decl, "QObject");
}
-bool QtUtils::isQObject(clang::QualType qt)
+bool clazy::isQObject(clang::QualType qt)
{
qt = TypeUtils::pointeeQualType(qt);
const auto t = qt.getTypePtrOrNull();
return t ? isQObject(t->getAsCXXRecordDecl()) : false;
}
-bool QtUtils::isConvertibleTo(const Type *source, const Type *target)
+bool clazy::isConvertibleTo(const Type *source, const Type *target)
{
if (!source || !target)
return false;
@@ -159,18 +169,18 @@ bool QtUtils::isConvertibleTo(const Type *source, const Type *target)
return false;
}
-bool QtUtils::isJavaIterator(CXXRecordDecl *record)
+bool clazy::isJavaIterator(CXXRecordDecl *record)
{
if (!record)
return false;
- static const vector<string> names = { "QHashIterator", "QMapIterator", "QSetIterator", "QListIterator",
- "QVectorIterator", "QLinkedListIterator", "QStringListIterator" };
+ static const vector<StringRef> names = { "QHashIterator", "QMapIterator", "QSetIterator", "QListIterator",
+ "QVectorIterator", "QLinkedListIterator", "QStringListIterator" };
- return clazy_std::contains(names, record->getNameAsString());
+ return clazy::contains(names, clazy::name(record));
}
-bool QtUtils::isJavaIterator(CXXMemberCallExpr *call)
+bool clazy::isJavaIterator(CXXMemberCallExpr *call)
{
if (!call)
return false;
@@ -178,19 +188,24 @@ bool QtUtils::isJavaIterator(CXXMemberCallExpr *call)
return isJavaIterator(call->getRecordDecl());
}
-bool QtUtils::isQtContainer(QualType t)
+bool clazy::isQtContainer(QualType t)
{
CXXRecordDecl *record = TypeUtils::typeAsRecord(t);
if (!record)
return false;
- const string typeName = record->getNameAsString();
- return clazy_std::any_of(QtUtils::qtContainers(), [typeName] (const string &container) {
+ return isQtContainer(record);
+}
+
+bool clazy::isQtContainer(const CXXRecordDecl *record)
+{
+ const StringRef typeName = clazy::name(record);
+ return clazy::any_of(clazy::qtContainers(), [typeName] (StringRef container) {
return container == typeName;
});
}
-bool QtUtils::containerNeverDetaches(const clang::VarDecl *valDecl, StmtBodyRange bodyRange) // clazy:exclude=function-args-by-value
+bool clazy::containerNeverDetaches(const clang::VarDecl *valDecl, StmtBodyRange bodyRange) // clazy:exclude=function-args-by-value
{
if (!valDecl)
return false;
@@ -210,19 +225,19 @@ bool QtUtils::containerNeverDetaches(const clang::VarDecl *valDecl, StmtBodyRang
return true;
}
-bool QtUtils::isAReserveClass(CXXRecordDecl *recordDecl)
+bool clazy::isAReserveClass(CXXRecordDecl *recordDecl)
{
if (!recordDecl)
return false;
static const std::vector<std::string> classes = {"QVector", "std::vector", "QList", "QSet"};
- return clazy_std::any_of(classes, [recordDecl](const string &className) {
+ return clazy::any_of(classes, [recordDecl](const string &className) {
return TypeUtils::derivesFrom(recordDecl, className);
});
}
-clang::CXXRecordDecl *QtUtils::getQObjectBaseClass(clang::CXXRecordDecl *recordDecl)
+clang::CXXRecordDecl *clazy::getQObjectBaseClass(clang::CXXRecordDecl *recordDecl)
{
if (!recordDecl)
return nullptr;
@@ -237,12 +252,12 @@ clang::CXXRecordDecl *QtUtils::getQObjectBaseClass(clang::CXXRecordDecl *recordD
}
-bool QtUtils::isConnect(FunctionDecl *func)
+bool clazy::isConnect(FunctionDecl *func)
{
return func && func->getQualifiedNameAsString() == "QObject::connect";
}
-bool QtUtils::connectHasPMFStyle(FunctionDecl *func)
+bool clazy::connectHasPMFStyle(FunctionDecl *func)
{
// Look for char* arguments
for (auto parm : Utils::functionParameters(func)) {
@@ -259,7 +274,7 @@ bool QtUtils::connectHasPMFStyle(FunctionDecl *func)
return true;
}
-CXXMethodDecl *QtUtils::pmfFromConnect(CallExpr *funcCall, int argIndex)
+CXXMethodDecl *clazy::pmfFromConnect(CallExpr *funcCall, int argIndex)
{
if (!funcCall)
return nullptr;
@@ -278,7 +293,7 @@ CXXMethodDecl *QtUtils::pmfFromConnect(CallExpr *funcCall, int argIndex)
}
-CXXMethodDecl *QtUtils::pmfFromUnary(Expr *expr)
+CXXMethodDecl *clazy::pmfFromUnary(Expr *expr)
{
if (auto uo = dyn_cast<UnaryOperator>(expr)) {
return pmfFromUnary(uo);
@@ -295,7 +310,7 @@ CXXMethodDecl *QtUtils::pmfFromUnary(Expr *expr)
if (!context)
return nullptr;
- CXXRecordDecl *record = dyn_cast<CXXRecordDecl>(context);
+ auto record = dyn_cast<CXXRecordDecl>(context);
if (!record)
return nullptr;
@@ -306,12 +321,16 @@ CXXMethodDecl *QtUtils::pmfFromUnary(Expr *expr)
return pmfFromUnary(dyn_cast<UnaryOperator>(call->getArg(1)));
} else if (auto staticCast = dyn_cast<CXXStaticCastExpr>(expr)) {
return pmfFromUnary(staticCast->getSubExpr());
+ } else if (auto callexpr = dyn_cast<CallExpr>(expr)) {
+ // QOverload case, go deeper one level to get to the UnaryOperator
+ if (callexpr->getNumArgs() == 1)
+ return pmfFromUnary(callexpr->getArg(0));
}
return nullptr;
}
-CXXMethodDecl *QtUtils::pmfFromUnary(UnaryOperator *uo)
+CXXMethodDecl *clazy::pmfFromUnary(UnaryOperator *uo)
{
if (!uo)
return nullptr;
@@ -328,7 +347,7 @@ CXXMethodDecl *QtUtils::pmfFromUnary(UnaryOperator *uo)
return nullptr;
}
-bool QtUtils::recordHasCtorWithParam(clang::CXXRecordDecl *record, const std::string &paramType, bool &ok, int &numCtors)
+bool clazy::recordHasCtorWithParam(clang::CXXRecordDecl *record, const std::string &paramType, bool &ok, int &numCtors)
{
ok = true;
numCtors = 0;