File indexing completed on 2024-05-12 05:41:01
0001 /* 0002 SPDX-FileCopyrightText: 2018 Sergio Martins <smartins@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "ifndef-define-typo.h" 0008 #include "QtUtils.h" 0009 #include "TypeUtils.h" 0010 #include "Utils.h" 0011 #include "levenshteindistance.h" 0012 0013 #include <clang/AST/AST.h> 0014 0015 using namespace clang; 0016 0017 IfndefDefineTypo::IfndefDefineTypo(const std::string &name, ClazyContext *context) 0018 : CheckBase(name, context) 0019 { 0020 enablePreProcessorCallbacks(); 0021 } 0022 0023 void IfndefDefineTypo::VisitMacroDefined(const Token ¯oNameTok) 0024 { 0025 if (!m_lastIfndef.empty()) { 0026 if (IdentifierInfo *ii = macroNameTok.getIdentifierInfo()) { 0027 maybeWarn(static_cast<std::string>(ii->getName()), macroNameTok.getLocation()); 0028 } 0029 } 0030 } 0031 0032 void IfndefDefineTypo::VisitDefined(const Token ¯oNameTok, const SourceRange &) 0033 { 0034 if (!m_lastIfndef.empty()) { 0035 if (IdentifierInfo *ii = macroNameTok.getIdentifierInfo()) { 0036 maybeWarn(static_cast<std::string>(ii->getName()), macroNameTok.getLocation()); 0037 } 0038 } 0039 } 0040 0041 void IfndefDefineTypo::VisitIfdef(SourceLocation, const Token &) 0042 { 0043 m_lastIfndef.clear(); 0044 } 0045 0046 void IfndefDefineTypo::VisitIfndef(SourceLocation, const Token ¯oNameTok) 0047 { 0048 if (IdentifierInfo *ii = macroNameTok.getIdentifierInfo()) { 0049 m_lastIfndef = static_cast<std::string>(ii->getName()); 0050 } 0051 } 0052 0053 void IfndefDefineTypo::VisitIf(SourceLocation, SourceRange, PPCallbacks::ConditionValueKind) 0054 { 0055 m_lastIfndef.clear(); 0056 } 0057 0058 void IfndefDefineTypo::VisitElif(SourceLocation, SourceRange, PPCallbacks::ConditionValueKind, SourceLocation) 0059 { 0060 m_lastIfndef.clear(); 0061 } 0062 0063 void IfndefDefineTypo::VisitElse(SourceLocation, SourceLocation) 0064 { 0065 m_lastIfndef.clear(); 0066 } 0067 0068 void IfndefDefineTypo::VisitEndif(SourceLocation, SourceLocation) 0069 { 0070 m_lastIfndef.clear(); 0071 } 0072 0073 void IfndefDefineTypo::maybeWarn(const std::string &define, SourceLocation loc) 0074 { 0075 if (m_lastIfndef == "Q_CONSTRUCTOR_FUNCTION") { // Transform into a list if more false-positives need to be added 0076 return; 0077 } 0078 0079 if (define == m_lastIfndef) { 0080 m_lastIfndef.clear(); 0081 return; 0082 } 0083 0084 if (define.length() < 4) { 0085 return; 0086 } 0087 0088 const int levDistance = levenshtein_distance(define, m_lastIfndef); 0089 if (levDistance < 3) { 0090 emitWarning(loc, std::string("Possible typo in define. ") + m_lastIfndef + " vs " + define); 0091 } 0092 }