2017-10-25 15:38:45 +02:00
|
|
|
#ifndef REFLECTIVE_RAPIDJSON_CODE_FACTORY_H
|
|
|
|
#define REFLECTIVE_RAPIDJSON_CODE_FACTORY_H
|
|
|
|
|
|
|
|
#include "./codegenerator.h"
|
2017-10-18 23:07:17 +02:00
|
|
|
|
2018-02-02 18:21:04 +01:00
|
|
|
#include <functional>
|
2017-10-18 23:07:17 +02:00
|
|
|
#include <iosfwd>
|
2017-10-21 00:32:42 +02:00
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
2017-10-18 23:07:17 +02:00
|
|
|
#include <vector>
|
|
|
|
|
2017-10-21 00:32:42 +02:00
|
|
|
namespace clang {
|
2017-10-24 01:00:40 +02:00
|
|
|
class CompilerInstance;
|
2017-10-21 00:32:42 +02:00
|
|
|
} // namespace clang
|
|
|
|
|
2017-10-18 23:07:17 +02:00
|
|
|
namespace ReflectiveRapidJSON {
|
|
|
|
|
2017-10-27 17:38:57 +02:00
|
|
|
class Consumer;
|
|
|
|
class Visitor;
|
|
|
|
|
2017-10-21 00:32:42 +02:00
|
|
|
/*!
|
|
|
|
* \brief The CodeFactory class produces additional (reflection) code for a specified list of C++ source files.
|
|
|
|
* \remarks
|
|
|
|
* - The code is written to a specified std::ostream instance.
|
|
|
|
* - The CodeFactory class is constituted by its underlying CodeGenerator instances.
|
|
|
|
*/
|
|
|
|
class CodeFactory {
|
2017-10-27 17:38:57 +02:00
|
|
|
friend class Consumer;
|
|
|
|
friend class Visitor;
|
|
|
|
|
2017-10-21 00:32:42 +02:00
|
|
|
public:
|
2021-05-16 19:09:46 +02:00
|
|
|
CodeFactory(std::string_view applicationPath, const std::vector<const char *> &sourceFiles, const std::vector<std::string_view> &clangOptions,
|
|
|
|
std::ostream &os);
|
2017-10-21 00:32:42 +02:00
|
|
|
~CodeFactory();
|
|
|
|
|
2017-10-23 18:59:55 +02:00
|
|
|
const std::vector<std::unique_ptr<CodeGenerator>> &generators() const;
|
2020-12-05 21:29:55 +01:00
|
|
|
template <typename GeneratorType, typename... Args> void addGenerator(Args &&...args);
|
|
|
|
template <typename GeneratorType, typename... Args> auto bindGenerator(Args &&...args);
|
2017-10-23 18:59:55 +02:00
|
|
|
|
2017-10-27 17:38:57 +02:00
|
|
|
bool run();
|
2017-10-24 01:00:40 +02:00
|
|
|
clang::CompilerInstance *compilerInstance();
|
|
|
|
void setCompilerInstance(clang::CompilerInstance *compilerInstance);
|
2018-02-03 15:47:25 +01:00
|
|
|
bool isErrorResilient() const;
|
|
|
|
void setErrorResilient(bool errorResilient);
|
2017-10-21 00:32:42 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
struct ToolInvocation;
|
|
|
|
|
2017-10-27 17:38:57 +02:00
|
|
|
void addDeclaration(clang::Decl *decl);
|
|
|
|
bool generate() const;
|
2017-10-21 00:32:42 +02:00
|
|
|
std::vector<std::string> makeClangArgs() const;
|
|
|
|
|
2021-05-16 19:09:46 +02:00
|
|
|
std::string_view m_applicationPath;
|
2017-10-21 00:32:42 +02:00
|
|
|
const std::vector<const char *> &m_sourceFiles;
|
2021-05-16 19:09:46 +02:00
|
|
|
const std::vector<std::string_view> &m_clangOptions;
|
2017-10-21 00:32:42 +02:00
|
|
|
std::ostream &m_os;
|
|
|
|
std::vector<std::unique_ptr<CodeGenerator>> m_generators;
|
|
|
|
std::unique_ptr<ToolInvocation> m_toolInvocation;
|
2017-10-24 01:00:40 +02:00
|
|
|
clang::CompilerInstance *m_compilerInstance;
|
2018-02-03 15:47:25 +01:00
|
|
|
bool m_errorResilient;
|
2017-10-21 00:32:42 +02:00
|
|
|
};
|
|
|
|
|
2018-02-03 15:45:15 +01:00
|
|
|
/*!
|
|
|
|
* \brief Instantiates a code generator of the specified type and adds it to the current instance.
|
|
|
|
* \remarks The specified \a args are forwarded to the generator's constructor.
|
|
|
|
*/
|
2020-12-05 21:29:55 +01:00
|
|
|
template <typename GeneratorType, typename... Args> void CodeFactory::addGenerator(Args &&...args)
|
2017-10-23 18:59:55 +02:00
|
|
|
{
|
2017-11-06 15:31:21 +01:00
|
|
|
m_generators.emplace_back(std::make_unique<GeneratorType>(*this, std::forward<Args>(args)...));
|
2017-10-23 18:59:55 +02:00
|
|
|
}
|
|
|
|
|
2018-02-02 18:21:04 +01:00
|
|
|
namespace Detail {
|
2018-02-03 15:45:15 +01:00
|
|
|
/*!
|
|
|
|
* \brief Wraps const references using std::cref() for use with std::bind().
|
|
|
|
*/
|
2018-02-02 18:21:04 +01:00
|
|
|
template <typename T> std::reference_wrapper<const T> wrapReferences(const T &val)
|
|
|
|
{
|
|
|
|
return std::cref(val);
|
|
|
|
}
|
|
|
|
|
2018-02-03 15:45:15 +01:00
|
|
|
/*!
|
|
|
|
* \brief Wraps mutable references using std::ref() for use with std::bind().
|
|
|
|
*/
|
2018-02-02 18:21:04 +01:00
|
|
|
template <typename T> std::reference_wrapper<T> wrapReferences(T &val)
|
|
|
|
{
|
|
|
|
return std::ref(val);
|
|
|
|
}
|
|
|
|
|
2018-02-03 15:45:15 +01:00
|
|
|
/*!
|
|
|
|
* \brief Forwards non-references for use with std::bind().
|
|
|
|
*/
|
2018-02-02 18:21:04 +01:00
|
|
|
template <typename T> T &&wrapReferences(T &&val)
|
|
|
|
{
|
|
|
|
return std::forward<T>(val);
|
|
|
|
}
|
|
|
|
} // namespace Detail
|
|
|
|
|
2018-02-03 15:45:15 +01:00
|
|
|
/*!
|
|
|
|
* \brief Returns a function which instantiates a code generator of the specified type and adds it to the current instance.
|
|
|
|
* \remarks
|
|
|
|
* - The specified \a args are forwarded to the generator's constructor.
|
|
|
|
* - No copy of \a args passed by reference is made.
|
|
|
|
*/
|
2020-12-05 21:29:55 +01:00
|
|
|
template <typename GeneratorType, typename... Args> auto CodeFactory::bindGenerator(Args &&...args)
|
2018-02-02 18:21:04 +01:00
|
|
|
{
|
|
|
|
return std::bind(&CodeFactory::addGenerator<GeneratorType, Args...>, this, Detail::wrapReferences(std::forward<Args>(args)...));
|
|
|
|
}
|
|
|
|
|
2018-02-03 15:45:15 +01:00
|
|
|
/*!
|
|
|
|
* \brief Returns the added generators.
|
|
|
|
*/
|
2017-10-23 18:59:55 +02:00
|
|
|
inline const std::vector<std::unique_ptr<CodeGenerator>> &CodeFactory::generators() const
|
|
|
|
{
|
|
|
|
return m_generators;
|
|
|
|
}
|
|
|
|
|
2018-02-03 15:45:15 +01:00
|
|
|
/*!
|
|
|
|
* \brief Returns the compiler instance.
|
|
|
|
* \remarks The is nullptr for a newly constructed factory and should be assigned by the frontend action.
|
|
|
|
*/
|
2017-10-24 01:00:40 +02:00
|
|
|
inline clang::CompilerInstance *CodeFactory::compilerInstance()
|
|
|
|
{
|
|
|
|
return m_compilerInstance;
|
|
|
|
}
|
|
|
|
|
2018-02-03 15:45:15 +01:00
|
|
|
/*!
|
|
|
|
* \brief Assigns the compiler instance.
|
|
|
|
* \remarks The factory does *not* take ownership.
|
|
|
|
*/
|
2017-10-24 01:00:40 +02:00
|
|
|
inline void CodeFactory::setCompilerInstance(clang::CompilerInstance *compilerInstance)
|
|
|
|
{
|
|
|
|
m_compilerInstance = compilerInstance;
|
|
|
|
}
|
|
|
|
|
2018-02-03 15:47:25 +01:00
|
|
|
/*!
|
|
|
|
* \brief Returns whether most errors will be turned into warnings (by default false).
|
|
|
|
*/
|
|
|
|
inline bool CodeFactory::isErrorResilient() const
|
|
|
|
{
|
|
|
|
return m_errorResilient;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Sets whether most errors will be turned into warnings (by default false).
|
|
|
|
*/
|
|
|
|
inline void CodeFactory::setErrorResilient(bool errorResilient)
|
|
|
|
{
|
|
|
|
m_errorResilient = errorResilient;
|
|
|
|
}
|
|
|
|
|
2017-10-21 00:32:42 +02:00
|
|
|
} // namespace ReflectiveRapidJSON
|
|
|
|
|
2017-10-25 15:38:45 +02:00
|
|
|
#endif // REFLECTIVE_RAPIDJSON_CODE_FACTORY_H
|