File indexing completed on 2024-05-19 05:42:00

0001 // ct_lvtclp_cpp_tool.h                                                   -*-C++-*-
0002 
0003 /*
0004 // Copyright 2023 Codethink Ltd <codethink@codethink.co.uk>
0005 // SPDX-License-Identifier: Apache-2.0
0006 //
0007 // Licensed under the Apache License, Version 2.0 (the "License");
0008 // you may not use this file except in compliance with the License.
0009 // You may obtain a copy of the License at
0010 //
0011 //     http://www.apache.org/licenses/LICENSE-2.0
0012 //
0013 // Unless required by applicable law or agreed to in writing, software
0014 // distributed under the License is distributed on an "AS IS" BASIS,
0015 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0016 // See the License for the specific language governing permissions and
0017 // limitations under the License.
0018 */
0019 
0020 #ifndef INCLUDED_CT_LVTCLP_TOOL
0021 #define INCLUDED_CT_LVTCLP_TOOL
0022 
0023 //@PURPOSE: Wrap create_codebase_db in a convenient interface
0024 //
0025 //@CLASSES:
0026 //  lvtclp::Tool Wraps create_codebase_db in an interface independent of
0027 //    command line arguments
0028 
0029 #include <lvtclp_export.h>
0030 
0031 #include <ct_lvtclp_filesystemscanner.h>
0032 #include <ct_lvtclp_headercallbacks.h>
0033 
0034 #include <ct_lvtmdb_objectstore.h>
0035 
0036 #include <clang/Tooling/CompilationDatabase.h>
0037 
0038 #include <filesystem>
0039 #include <initializer_list>
0040 #include <string>
0041 #include <vector>
0042 
0043 #include <QLoggingCategory>
0044 #include <QObject>
0045 #include <QString>
0046 
0047 namespace Codethink::lvtclp {
0048 
0049 // =======================
0050 // class CppTool
0051 // =======================
0052 
0053 class LVTCLP_EXPORT CppTool : public QObject {
0054     Q_OBJECT
0055 
0056   private:
0057     // TYPES
0058     struct Private;
0059 
0060     // DATA
0061     std::unique_ptr<Private> d;
0062 
0063   public:
0064     enum class UseSystemHeaders { e_Yes, e_No, e_Query };
0065 
0066     // CREATORS
0067     CppTool(std::filesystem::path sourcePath,
0068             const std::vector<std::filesystem::path>& compileCommandsJsons,
0069             const std::filesystem::path& databasePath,
0070             unsigned numThreads = 1,
0071             const std::vector<std::string>& ignoreList = {},
0072             const std::vector<std::filesystem::path>& nonLakosianDirs = {},
0073             std::vector<std::pair<std::string, std::string>> thirdPartyDirs = {},
0074             bool printToConsole = false);
0075 
0076     CppTool(std::filesystem::path sourcePath,
0077             const clang::tooling::CompileCommand& compileCommand,
0078             const std::filesystem::path& databasePath,
0079             const std::vector<std::string>& ignoreList = {},
0080             const std::vector<std::filesystem::path>& nonLakosianDirs = {},
0081             std::vector<std::pair<std::string, std::string>> thirdPartyDirs = {},
0082             bool printToConsole = false);
0083 
0084     CppTool(std::filesystem::path sourcePath,
0085             const clang::tooling::CompilationDatabase& db,
0086             const std::filesystem::path& databasePath,
0087             unsigned numThreads = 1,
0088             const std::vector<std::string>& ignoreList = {},
0089             const std::vector<std::filesystem::path>& nonLakosianDirs = {},
0090             std::vector<std::pair<std::string, std::string>> thirdPartyDirs = {},
0091             bool printToConsole = false);
0092 
0093     ~CppTool() noexcept override;
0094 
0095     // MANIPULATORS
0096     lvtmdb::ObjectStore& getObjectStore();
0097     void setSharedMemDb(std::shared_ptr<lvtmdb::ObjectStore> const& sharedMemDb);
0098 
0099     // Get a reference to the output database.
0100     // The reference is valid so long as this Tool instance remains valid
0101 
0102     void setUseSystemHeaders(UseSystemHeaders value);
0103     // defines if we should use, not use, or query if we need to use the system headers.
0104     // This needed because some applications have a --query-system-headers argument
0105     // that returns true/false, so we can use the cached result instead of
0106     // creating a clang tool always, and filling the stdout with bogus information.
0107     // The default value is UseSystemHeaders::e_Query
0108 
0109     bool findPhysicalEntities(bool doIncremental = true);
0110     // Find files, components, packages, and package groups
0111     // Returns true on success, false otherwise.
0112     // If doIncremental is false, everything is re-generated no matter what
0113     // incremental updates things needs to be done
0114 
0115     bool runPhysical(bool skipScan = false);
0116     // Run only the steps needed to get the physical dependency graph
0117     // Returns true on success, false otherwise.
0118     // If skipScan is true, findPhysicalEntities will not be re-run. It is
0119     // the caller's responsibility to make sure it has already been run in
0120     // this case
0121 
0122     bool runFull(bool skipPhysical = false);
0123     // Build a full database
0124     // Returns true on success, false otherwise.
0125 
0126     void setShowDatabaseErrors(bool value);
0127     // enables sending database error information to the consumer
0128 
0129     void setPrintToConsole(bool b);
0130 
0131     void cancelRun();
0132     // Cancel mid-way through a runPhysical() or runFull(). If one of these
0133     // are not running, this function has no effect. It is safe to call this
0134     // from a different thread than that running run*()
0135 
0136     [[nodiscard]] bool finalizingThreads() const;
0137     // when we cancelRun, this is true, false otherwise.
0138     // used to ignore some elements on the UI.
0139 
0140     // ACCESSORS
0141     [[nodiscard]] bool lastRunMadeChanges() const;
0142     // for testing: true only if there was work to do on the most recent run
0143 
0144     void setHeaderLocationCallback(HeaderCallbacks::HeaderLocationCallback_f const& headerLocationCallback);
0145 
0146     void setHandleCppCommentsCallback(
0147         std::function<void(
0148             const std::string& filename, const std::string& briefText, unsigned startLine, unsigned endLine)> const&
0149             handleCppCommentsCallback);
0150 
0151     Q_SIGNAL void processingFileNotification(QString path);
0152     // notifies when we have a clang::FrontendAction::BeginSourceFileAction
0153 
0154     Q_SIGNAL void aboutToCallClangNotification(int size);
0155     // publishes the size of the compilation database before we hand it to
0156     // clang
0157 
0158     Q_SIGNAL void messageFromThread(const QString& message, long threadId);
0159     // The thread got some information and want us to display it.
0160 
0161     void messageCallback(const std::string& message, long threadId);
0162     // emits messageFromThread
0163 
0164   private:
0165     // PRIVATE MANIPULATORS
0166     bool ensureSetup();
0167     // Make sure the code and compilation databases are ready.
0168     // Returns true on success, false otherwise.
0169     bool processCompilationDatabase();
0170     bool ensureDatabaseIsOpen();
0171 
0172     void setupIncrementalUpdate(FilesystemScanner::IncrementalResult& res, bool doIncremental);
0173 
0174     void setDbReadiness(const std::string& readiness);
0175 };
0176 
0177 } // namespace Codethink::lvtclp
0178 
0179 #endif // INCLUDED_CT_LVTCLP_TOOL