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

0001 /*
0002     SPDX-FileCopyrightText: 2018 Sergio Martins <smartins@kde.org>
0003     SPDX-FileCopyrightText: 2023 Ahmad Samir <a.samirh78@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "qt-keyword-emit.h"
0009 #include "ClazyContext.h"
0010 #include "FixItUtils.h"
0011 #include "PreProcessorVisitor.h"
0012 #include "clazy_stl.h"
0013 
0014 #include <clang/Basic/Diagnostic.h>
0015 #include <clang/Basic/IdentifierTable.h>
0016 #include <clang/Basic/SourceManager.h>
0017 #include <clang/Lex/MacroInfo.h>
0018 #include <clang/Lex/Token.h>
0019 #include <llvm/ADT/StringRef.h>
0020 
0021 #include <algorithm>
0022 #include <ctype.h>
0023 #include <string_view>
0024 #include <vector>
0025 
0026 using namespace clang;
0027 
0028 QtKeywordEmit::QtKeywordEmit(const std::string &name, ClazyContext *context)
0029     : CheckBase(name, context)
0030 {
0031     enablePreProcessorCallbacks();
0032     context->enablePreprocessorVisitor();
0033 }
0034 
0035 void QtKeywordEmit::VisitMacroExpands(const Token &macroNameTok, const SourceRange &range, const clang::MacroInfo *minfo)
0036 {
0037     IdentifierInfo *ii = macroNameTok.getIdentifierInfo();
0038     if (!ii || !minfo)
0039         return;
0040 
0041     if (auto ppvisitor = m_context->preprocessorVisitor) {
0042         // Save some CPU cycles. No point in running if QT_NO_KEYWORDS
0043         if (ppvisitor->isQT_NO_KEYWORDS())
0044             return;
0045     }
0046 
0047     static const std::string emitKeyword{"emit"};
0048     if (emitKeyword != std::string_view{ii->getName()})
0049         return;
0050 
0051     // Make sure the macro is Qt's. It must be defined in Qt's headers, not 3rdparty
0052     const std::string qtheader{sm().getFilename(sm().getSpellingLoc(minfo->getDefinitionLoc()))};
0053     // qobjectdefs.h in Qt5 or qtmetamacros.h in Qt6
0054     if (!clazy::endsWithAny(qtheader, {"qobjectdefs.h", "qtmetamacros.h"}))
0055         return;
0056 
0057     std::vector<FixItHint> fixits{clazy::createReplacement(range, "Q_EMIT")};
0058     emitWarning(range.getBegin(), "Using Qt (" + emitKeyword + ") keyword", fixits);
0059 }