#ifndef CXXFOOZZ_INCLUDE_SEQUENCEGEN_HPP_ #define CXXFOOZZ_INCLUDE_SEQUENCEGEN_HPP_ #include "statement.hpp" #include "type.hpp" #include "program-context.hpp" namespace cxxfoozz { class TestCase { public: TestCase( std::vector> statements, std::shared_ptr template_type_context ); const std::vector> &GetStatements() const; std::vector> &GetMutableStatements(); const std::shared_ptr &GetTemplateTypeContext() const; std::string DebugString(const std::shared_ptr &prog_ctx) const; bool Verify() const; private: std::vector> statements_; std::shared_ptr template_type_context_; // TODO: Do we need tt_ctx in TC level? }; namespace seqgen { class ResolveOperandSpec { public: ResolveOperandSpec( const TypeWithModifier &type, std::vector> &statements, std::shared_ptr template_type_context, bool force_avail_op ); const TypeWithModifier &GetType() const; std::vector> &GetStatements() const; const std::shared_ptr &GetTemplateTypeContext() const; bool IsForceAvailOp() const; private: const TypeWithModifier &type_; std::vector> &statements_; std::shared_ptr template_type_context_; bool force_avail_op_; }; class GenTCForMethodSpec { public: GenTCForMethodSpec( std::shared_ptr target, std::shared_ptr template_type_context, bool force_avail_op = false ); GenTCForMethodSpec( std::shared_ptr target, std::shared_ptr template_type_context, std::vector> context, int placement_idx = 0, bool force_avail_op = false ); const std::shared_ptr &GetTarget() const; const std::shared_ptr &GetTemplateTypeContext() const; const std::vector> &GetStatementContext() const; int GetPlacementIdx() const; bool IsForceAvailOp() const; private: std::shared_ptr target_; std::shared_ptr template_type_context_; std::vector> statement_context_; int placement_idx_ = 0; // placement_idx == 0 simply means cannot utilize context as ref :) bool force_avail_op_ = false; }; } // namespace seqgen class TestCaseGenerator { public: TestCaseGenerator(std::shared_ptr cut, std::shared_ptr context); TestCase GenForMethod(const seqgen::GenTCForMethodSpec &target) const; private: std::shared_ptr cut_; std::shared_ptr context_; }; class CreatorCyclicChecker { public: CreatorCyclicChecker(); bool IsCyclic(const std::shared_ptr &creator); private: std::multiset> used_; static int kCycleThreshold; }; class OperandResolver { public: explicit OperandResolver(std::shared_ptr context); Operand ResolveOperand(const seqgen::ResolveOperandSpec &spec); std::vector> GetAssignableStatements( const TypeWithModifier &target_type, const std::shared_ptr &op_stmt_ctx, // pass nullptr for non-mutation const TestCase &tc_ctx ); bpstd::optional ResolveUsingAssignableStatements(const seqgen::ResolveOperandSpec &spec); friend class STLOperandResolver; private: Operand ResolveOperandPrimitiveType(const seqgen::ResolveOperandSpec &spec); Operand ResolveOperandClassType(const seqgen::ResolveOperandSpec &spec); Operand ResolveOperandTemplateTypenameType(const seqgen::ResolveOperandSpec &spec); Operand ResolveOperandEnumType(const seqgen::ResolveOperandSpec &spec); Operand ResolveOperandTemplateTypenameSpcType(const seqgen::ResolveOperandSpec &spec); Operand ResolveOperandTemplateTypenameSpcTypeForSTL(const seqgen::ResolveOperandSpec &spec); std::shared_ptr context_; }; class STLOperandResolver { public: explicit STLOperandResolver(OperandResolver &operand_resolver); Operand Handle(const seqgen::ResolveOperandSpec &spec); private: Operand ResolveRegularContainer( const seqgen::ResolveOperandSpec &spec, const std::shared_ptr &stl_type, const std::vector &tt_insts ); Operand ResolveArray(const seqgen::ResolveOperandSpec &spec, const std::vector &tt_insts); Operand ResolveKeyValueContainer( const seqgen::ResolveOperandSpec &spec, const std::shared_ptr &stl_type, const std::vector &tt_insts ); Operand ResolvePair(const seqgen::ResolveOperandSpec &spec, const std::vector &tt_insts); Operand ResolveTuple( const seqgen::ResolveOperandSpec &spec, const std::vector &tt_insts ); Operand ResolveSmartPointer( const seqgen::ResolveOperandSpec &spec, const std::shared_ptr &stl_type, const std::vector &tt_insts ); Operand ResolveString(const seqgen::ResolveOperandSpec &spec, const std::vector &tt_insts); private: static const int kMaxElementsExclusive; static const int kMaxElementsForStringExclusive; OperandResolver &operand_resolver_; }; } #endif //CXXFOOZZ_INCLUDE_SEQUENCEGEN_HPP_