File indexing completed on 2024-04-28 16:57:48

0001 /*
0002     This file is part of the clazy static checker.
0003 
0004     Copyright (C) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
0005     Author: SĂ©rgio Martins <sergio.martins@kdab.com>
0006 
0007     Copyright (C) 2015-2016 Sergio Martins <smartins@kde.org>
0008 
0009     This library is free software; you can redistribute it and/or
0010     modify it under the terms of the GNU Library General Public
0011     License as published by the Free Software Foundation; either
0012     version 2 of the License, or (at your option) any later version.
0013 
0014     This library is distributed in the hope that it will be useful,
0015     but WITHOUT ANY WARRANTY; without even the implied warranty of
0016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0017     Library General Public License for more details.
0018 
0019     You should have received a copy of the GNU Library General Public License
0020     along with this library; see the file COPYING.LIB.  If not, write to
0021     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0022     Boston, MA 02110-1301, USA.
0023 */
0024 
0025 #ifndef CLANG_LAZY_CHECK_MANAGER_H
0026 #define CLANG_LAZY_CHECK_MANAGER_H
0027 
0028 #include "checkbase.h"
0029 
0030 #include <clang/Lex/PreprocessorOptions.h>
0031 
0032 #include <functional>
0033 #include <mutex>
0034 #include <unordered_map>
0035 #include <vector>
0036 #include <utility>
0037 #include <string>
0038 
0039 class ClazyContext;
0040 
0041 struct RegisteredFixIt {
0042     typedef std::vector<RegisteredFixIt> List;
0043     RegisteredFixIt() : id(-1) {}
0044     RegisteredFixIt(int id, const std::string &name) : id(id), name(name) {}
0045     int id = -1;
0046     std::string name;
0047     bool operator==(const RegisteredFixIt &other) const { return id == other.id; }
0048 };
0049 
0050 using FactoryFunction = std::function<CheckBase*(ClazyContext *context)>;
0051 
0052 struct RegisteredCheck {
0053     enum Option {
0054         Option_None = 0,
0055         Option_Qt4Incompatible = 1,
0056         Option_VisitsStmts = 2,
0057         Option_VisitsDecls = 4
0058     };
0059 
0060     typedef std::vector<RegisteredCheck> List;
0061     typedef int Options;
0062 
0063     std::string name;
0064     CheckLevel level;
0065     FactoryFunction factory;
0066     Options options;
0067     bool operator==(const RegisteredCheck &other) const { return name == other.name; }
0068 };
0069 
0070 inline bool checkLessThan(const RegisteredCheck &c1, const RegisteredCheck &c2)
0071 {
0072     return c1.name < c2.name;
0073 }
0074 
0075 inline bool checkLessThanByLevel(const RegisteredCheck &c1, const RegisteredCheck &c2)
0076 {
0077     if (c1.level == c2.level)
0078         return checkLessThan(c1, c2);
0079 
0080     return c1.level < c2.level;
0081 }
0082 
0083 class CheckManager
0084 {
0085 public:
0086     /**
0087      * @note You must hold the CheckManager lock when operating on the instance
0088      *
0089      * @sa lock()
0090      */
0091     static CheckManager *instance();
0092 
0093     static std::mutex &lock() { return m_lock; }
0094     RegisteredCheck::List availableChecks(CheckLevel maxLevel) const;
0095     RegisteredCheck::List requestedChecksThroughEnv(std::vector<std::string> &userDisabledChecks) const;
0096     std::vector<std::string> checksAsErrors() const;
0097 
0098     RegisteredCheck::List::const_iterator checkForName(const RegisteredCheck::List &checks, const std::string &name) const;
0099     RegisteredCheck::List checksForCommaSeparatedString(const std::string &str) const;
0100     RegisteredCheck::List checksForCommaSeparatedString(const std::string &str,
0101                                                         std::vector<std::string> &userDisabledChecks) const;
0102     RegisteredFixIt::List availableFixIts(const std::string &checkName) const;
0103 
0104 
0105     /**
0106      * Returns all the requested checks.
0107      * This is a union of the requested checks via env variable and via arguments passed to compiler
0108      */
0109     RegisteredCheck::List requestedChecks(std::vector<std::string> &args, bool qt4Compat);
0110     std::vector<std::pair<CheckBase*, RegisteredCheck>> createChecks(const RegisteredCheck::List &requestedChecks, ClazyContext *context);
0111 
0112     static void removeChecksFromList(RegisteredCheck::List &list, std::vector<std::string> &checkNames);
0113 
0114 private:
0115     CheckManager();
0116     static std::mutex m_lock;
0117 
0118     void registerChecks();
0119     void registerFixIt(int id, const std::string &fititName, const std::string &checkName);
0120     void registerCheck(const RegisteredCheck &check);
0121     bool checkExists(const std::string &name) const;
0122     RegisteredCheck::List checksForLevel(int level) const;
0123     CheckBase* createCheck(const std::string &name, ClazyContext *context);
0124     std::string checkNameForFixIt(const std::string &) const;
0125     RegisteredCheck::List m_registeredChecks;
0126     std::unordered_map<std::string, std::vector<RegisteredFixIt>> m_fixitsByCheckName;
0127     std::unordered_map<std::string, RegisteredFixIt > m_fixitByName;
0128 };
0129 
0130 #endif