File indexing completed on 2024-05-12 05:41:04

0001 /*
0002     SPDX-FileCopyrightText: 2021 Klarälvdalens Datakonsult AB a KDAB Group company info@kdab.com
0003     SPDX-FileContributor: Waqar Ahmed <waqar.ahmed@kdab.com>
0004 
0005     SPDX-FileCopyrightText: 2021 Waqar Ahmed <waqar.17a@gmail.com>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #include "use-arrow-operator-instead-of-data.h"
0011 
0012 #include "HierarchyUtils.h"
0013 #include <clang/AST/ExprCXX.h>
0014 
0015 using namespace clang;
0016 
0017 UseArrowOperatorInsteadOfData::UseArrowOperatorInsteadOfData(const std::string &name, ClazyContext *context)
0018     : CheckBase(name, context)
0019 {
0020 }
0021 
0022 void UseArrowOperatorInsteadOfData::VisitStmt(clang::Stmt *stmt)
0023 {
0024     auto *ce = dyn_cast<CXXMemberCallExpr>(stmt);
0025     if (!ce) {
0026         return;
0027     }
0028 
0029     auto vec = Utils::callListForChain(ce);
0030     if (vec.size() < 2) {
0031         return;
0032     }
0033 
0034     CallExpr *callExpr = vec.at(vec.size() - 1);
0035 
0036     FunctionDecl *funcDecl = callExpr->getDirectCallee();
0037     if (!funcDecl) {
0038         return;
0039     }
0040     const std::string func = clazy::qualifiedMethodName(funcDecl);
0041 
0042     static const std::vector<std::string> whiteList{"QScopedPointer::data", "QPointer::data", "QSharedPointer::data", "QSharedDataPointer::data"};
0043 
0044     bool accepted = clazy::any_of(whiteList, [func](const std::string &f) {
0045         return f == func;
0046     });
0047     if (!accepted) {
0048         return;
0049     }
0050 
0051     std::vector<FixItHint> fixits;
0052 
0053     constexpr int MinPossibleColonPos = sizeof("QPointer") - 1;
0054     const std::string ClassName = func.substr(0, func.find(':', MinPossibleColonPos));
0055 
0056     auto begin = callExpr->getExprLoc();
0057     const auto end = callExpr->getEndLoc();
0058 
0059     // find '.' in ptr.data()
0060     int dotOffset = 0;
0061     const char *d = m_sm.getCharacterData(begin);
0062     while (*d != '.') {
0063         dotOffset--;
0064         d--;
0065     }
0066     begin = begin.getLocWithOffset(dotOffset);
0067 
0068     const SourceRange sourceRange{begin, end};
0069     FixItHint removal = FixItHint::CreateRemoval(sourceRange);
0070     fixits.push_back(std::move(removal));
0071 
0072     emitWarning(callExpr->getBeginLoc(), "Use operator -> directly instead of " + ClassName + "::data()->", fixits);
0073 }