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

0001 // ct_lvtclp_testutil.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_TESTUTIL
0021 #define INCLUDED_CT_LVTCLP_TESTUTIL
0022 
0023 #include <ct_lvtclp_clputil.h>
0024 
0025 #include <ct_lvtmdb_objectstore.h>
0026 
0027 #include <filesystem>
0028 #include <initializer_list>
0029 #include <memory>
0030 #include <string>
0031 #include <utility>
0032 #include <vector>
0033 
0034 #include <clang/Tooling/CompilationDatabase.h>
0035 
0036 namespace Codethink::lvtclp {
0037 
0038 struct Test_Util {
0039     // Not for use outside lvtclp tests
0040 
0041     static bool runOnCode(lvtmdb::ObjectStore& mdb, const std::string& source, const std::string& fileName);
0042     // Run the AST parse on the c++ source in `source`, saving to database
0043     // `session` and acting as though `source` has the file name `fileName`
0044 
0045     static bool isAExists(const std::string& derivedClassQualifiedName,
0046                           const std::string& baseClassQualifiedName,
0047                           lvtmdb::ObjectStore& session);
0048     static bool usesInTheImplementationExists(const std::string& sourceQualifiedName,
0049                                               const std::string& targetQualifiedName,
0050                                               lvtmdb::ObjectStore& session);
0051     static bool usesInTheInterfaceExists(const std::string& sourceQualifiedName,
0052                                          const std::string& targetQualifiedName,
0053                                          lvtmdb::ObjectStore& session);
0054     // Test if a relationship exists in the database. Expects an active
0055     // database transaction
0056 
0057     static bool classDefinedInFile(const std::string& classQualifiedName,
0058                                    const std::string& fileQualifiedName,
0059                                    lvtmdb::ObjectStore& session);
0060     // Test if a class is defined in a particular file. Expects an active
0061     // database transaction
0062 
0063     static bool createFile(const std::filesystem::path& path, const std::string& contents = "");
0064     // create a file at path, deleting anything already there with that name
0065     // contents is written to the file
0066     // returns true on success, false otherwise
0067 };
0068 
0069 class StaticCompilationDatabase : public LvtCompilationDatabase {
0070     // A compilation database constructable from compile commands
0071 
0072   private:
0073     // DATA
0074     std::vector<clang::tooling::CompileCommand> d_compileCommands;
0075     const std::filesystem::path d_directory;
0076 
0077   public:
0078     // CREATORS
0079     explicit StaticCompilationDatabase(std::initializer_list<clang::tooling::CompileCommand> commands,
0080                                        std::filesystem::path directory);
0081     // Construct directly from commands
0082 
0083     explicit StaticCompilationDatabase(std::initializer_list<std::pair<std::string, std::string>> paths,
0084                                        const std::string& command,
0085                                        const std::vector<std::string>& arguments,
0086                                        std::filesystem::path directory);
0087     // This constructor constructs the clang::tooling::CompileCommands for you
0088     // paths is a series of pairs of <input path, output path>
0089     // command is the compiler path
0090     // arguments are common arguments to be added to every command line
0091     // directory is the directory to run from
0092 
0093     [[nodiscard]] std::vector<clang::tooling::CompileCommand>
0094     getCompileCommands(llvm::StringRef FilePath) const override;
0095 
0096     [[nodiscard]] std::vector<std::string> getAllFiles() const override;
0097 
0098     [[nodiscard]] std::vector<clang::tooling::CompileCommand> getAllCompileCommands() const override;
0099 
0100     [[nodiscard]] bool containsFile(const std::string& file) const override;
0101 
0102     [[nodiscard]] bool containsPackage(const std::string& str) const override;
0103 };
0104 
0105 struct ModelUtil {
0106     // Easy language for specifying and checking the contents of a database:
0107 
0108     // PUBLIC TYPES
0109     struct SourceFileModel {
0110         std::string path;
0111         bool isHeader;
0112         std::string pkg;
0113         std::string component;
0114         std::vector<std::string> namespaces;
0115         std::vector<std::string> classes;
0116         std::vector<std::string> includes;
0117     };
0118 
0119     struct ComponentModel {
0120         std::string qualifiedName;
0121         std::string name;
0122         std::vector<std::string> files;
0123         std::vector<std::string> deps;
0124     };
0125 
0126     struct PackageModel {
0127         std::string name;
0128         std::string parent;
0129         std::vector<std::string> udts;
0130         std::vector<std::string> components;
0131         std::vector<std::string> dependencies;
0132     };
0133 
0134     struct UDTModel {
0135         std::string qualifiedName;
0136         std::string nmspc;
0137         std::string pkg;
0138         std::vector<std::string> usesInImpl;
0139         std::vector<std::string> usesInInter;
0140         std::vector<std::string> isA;
0141         std::vector<std::string> methods;
0142         std::vector<std::string> fields;
0143     };
0144 
0145     // CLASS METHODS
0146     static void checkSourceFiles(lvtmdb::ObjectStore& store,
0147                                  const std::initializer_list<SourceFileModel>& files,
0148                                  bool printToConsole = false);
0149     // Check that the source files described by models are all in the database
0150     // session with the described properties
0151 
0152     static void checkComponents(lvtmdb::ObjectStore& store,
0153                                 const std::initializer_list<ComponentModel>& checkComponents);
0154     // Check that the components described by models are all in the database
0155     // session with the described properties
0156 
0157     static void checkPackages(lvtmdb::ObjectStore& store, const std::initializer_list<PackageModel>& pkgs);
0158     // Check that the packages and package groups described by models are
0159     // all in the database session with the described properties
0160 
0161     static void checkUDTs(lvtmdb::ObjectStore& store, const std::initializer_list<UDTModel>& udts);
0162     // Check that the types described by models are all in the database
0163     // session with the described properties
0164 };
0165 
0166 } // namespace Codethink::lvtclp
0167 
0168 #pragma push_macro("slots")
0169 #undef slots
0170 #include <pybind11/embed.h>
0171 #include <pybind11/pybind11.h>
0172 #pragma pop_macro("slots")
0173 
0174 namespace py = pybind11;
0175 struct PyDefaultGilReleasedContext {
0176     py::scoped_interpreter pyInterp;
0177     py::gil_scoped_release pyGilDefaultReleased;
0178 };
0179 
0180 #endif // INCLUDED_CT_LVTCLP_TESTUTIL