mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add assignment statement.
This commit is contained in:
parent
4b40b40bb6
commit
f6242ef6b7
@ -41,6 +41,7 @@
|
||||
*
|
||||
*/
|
||||
#define GENERATORLIST(MACRO, SEP, ENDSEP) \
|
||||
MACRO(AssignmentStmtGenerator) SEP \
|
||||
MACRO(BlockStmtGenerator) SEP \
|
||||
MACRO(ContractGenerator) SEP \
|
||||
MACRO(FunctionGenerator) SEP \
|
||||
|
@ -265,9 +265,51 @@ string FunctionState::params(Params _p)
|
||||
return "(" + boost::algorithm::join(params, ",") + ")";
|
||||
}
|
||||
|
||||
string AssignmentStmtGenerator::visit()
|
||||
{
|
||||
ExpressionGenerator exprGen{state};
|
||||
auto lhs = exprGen.expression();
|
||||
if (!lhs.has_value())
|
||||
return "\n";
|
||||
auto rhs = exprGen.expression(lhs.value().first);
|
||||
if (!rhs.has_value())
|
||||
return "\n";
|
||||
return lhs.value().second + " = " + rhs.value().second + ";\n";
|
||||
}
|
||||
|
||||
void StatementGenerator::setup()
|
||||
{
|
||||
addGenerators({
|
||||
{mutator->generator<BlockStmtGenerator>(), 1},
|
||||
{mutator->generator<AssignmentStmtGenerator>(), 1}
|
||||
});
|
||||
}
|
||||
|
||||
string StatementGenerator::visit()
|
||||
{
|
||||
return visitChildren();
|
||||
}
|
||||
|
||||
void BlockStmtGenerator::setup()
|
||||
{
|
||||
addGenerators({
|
||||
{mutator->generator<StatementGenerator>(), s_maxStatements},
|
||||
});
|
||||
}
|
||||
|
||||
string BlockStmtGenerator::visit()
|
||||
{
|
||||
return "\n" + indentation() + "{}\n";
|
||||
if (nestingTooDeep())
|
||||
return "\n";
|
||||
|
||||
incrementNestingDepth();
|
||||
ostringstream block;
|
||||
block << indentation() + "{\n";
|
||||
state->indent();
|
||||
block << visitChildren();
|
||||
state->unindent();
|
||||
block << indentation() << "}\n";
|
||||
return block.str();
|
||||
}
|
||||
|
||||
void FunctionGenerator::setup()
|
||||
@ -303,10 +345,54 @@ string FunctionGenerator::visit()
|
||||
if (!state->currentFunctionState()->outputs.empty())
|
||||
function << " returns"
|
||||
<< state->currentFunctionState()->params(FunctionState::Params::OUTPUT);
|
||||
function << generator<BlockStmtGenerator>()->visit();
|
||||
function << "\n" << generator<BlockStmtGenerator>()->visit();
|
||||
return function.str();
|
||||
}
|
||||
|
||||
pair<SolidityTypePtr, string> ExpressionGenerator::randomLValueExpression()
|
||||
{
|
||||
LValueExpr exprType = static_cast<LValueExpr>(
|
||||
state->uRandDist->distributionOneToN(static_cast<size_t>(LValueExpr::TYPEMAX) - 1)
|
||||
);
|
||||
switch (exprType)
|
||||
{
|
||||
case LValueExpr::VARREF:
|
||||
{
|
||||
auto liveVariables = state->currentFunctionState()->inputs |
|
||||
ranges::views::transform([](auto& _item) { return _item; }) |
|
||||
ranges::to<vector<pair<SolidityTypePtr, string>>>();
|
||||
liveVariables += state->currentFunctionState()->outputs |
|
||||
ranges::views::transform([](auto& _item) { return _item; }) |
|
||||
ranges::to<vector<pair<SolidityTypePtr, string>>>();
|
||||
return liveVariables[state->uRandDist->distributionOneToN(liveVariables.size()) - 1];
|
||||
}
|
||||
default:
|
||||
solAssert(false, "");
|
||||
}
|
||||
}
|
||||
|
||||
optional<pair<SolidityTypePtr, string>> ExpressionGenerator::expression()
|
||||
{
|
||||
auto currentFunctionState = state->currentFunctionState();
|
||||
// TODO: Remove this barrier once we support more expression types.
|
||||
if (currentFunctionState->inputs.empty() && currentFunctionState->outputs.empty())
|
||||
return nullopt;
|
||||
return randomLValueExpression();
|
||||
}
|
||||
|
||||
optional<pair<SolidityTypePtr, string>> ExpressionGenerator::expression(SolidityTypePtr _type)
|
||||
{
|
||||
auto liveTypedVariables = state->currentFunctionState()->inputs |
|
||||
ranges::views::filter([&_type](auto& _item) { return _item.first == _type; }) |
|
||||
ranges::to<vector<pair<SolidityTypePtr, string>>>();
|
||||
liveTypedVariables += state->currentFunctionState()->outputs |
|
||||
ranges::views::filter([&_type](auto& _item) { return _item.first == _type; }) |
|
||||
ranges::to<vector<pair<SolidityTypePtr, string>>>();
|
||||
if (liveTypedVariables.empty())
|
||||
return nullopt;
|
||||
return liveTypedVariables[state->uRandDist->distributionOneToN(liveTypedVariables.size()) - 1];
|
||||
}
|
||||
|
||||
optional<SolidityTypePtr> TypeProvider::type(SolidityTypePtr _type)
|
||||
{
|
||||
vector<SolidityTypePtr> matchingTypes = state->currentFunctionState()->inputs |
|
||||
|
@ -619,13 +619,15 @@ struct ExpressionGenerator
|
||||
ExpressionGenerator(std::shared_ptr<TestState> _state): state(std::move(_state))
|
||||
{}
|
||||
|
||||
enum class Expr: size_t
|
||||
enum class LValueExpr: size_t
|
||||
{
|
||||
VARREF = 1,
|
||||
TYPEMAX
|
||||
};
|
||||
|
||||
std::string expression(SolidityTypePtr _type);
|
||||
std::optional<std::pair<SolidityTypePtr, std::string>> expression(SolidityTypePtr _type);
|
||||
std::optional<std::pair<SolidityTypePtr, std::string>> expression();
|
||||
std::pair<SolidityTypePtr, std::string> randomLValueExpression();
|
||||
|
||||
std::shared_ptr<TestState> state;
|
||||
};
|
||||
@ -807,19 +809,47 @@ public:
|
||||
explicit StatementGenerator(std::shared_ptr<SolidityGenerator> _mutator):
|
||||
GeneratorBase(std::move(_mutator))
|
||||
{}
|
||||
void setup() override {}
|
||||
std::string visit() override { return {}; }
|
||||
void setup() override;
|
||||
std::string visit() override;
|
||||
std::string name() override { return "Statement generator"; }
|
||||
};
|
||||
|
||||
class AssignmentStmtGenerator: public GeneratorBase
|
||||
{
|
||||
public:
|
||||
explicit AssignmentStmtGenerator(std::shared_ptr<SolidityGenerator> _mutator):
|
||||
GeneratorBase(std::move(_mutator))
|
||||
{}
|
||||
std::string visit() override;
|
||||
std::string name() override { return "Assignment statement generator"; }
|
||||
};
|
||||
|
||||
class BlockStmtGenerator: public GeneratorBase
|
||||
{
|
||||
public:
|
||||
explicit BlockStmtGenerator(std::shared_ptr<SolidityGenerator> _mutator):
|
||||
GeneratorBase(std::move(_mutator))
|
||||
GeneratorBase(std::move(_mutator)),
|
||||
m_nestingDepth(0)
|
||||
{}
|
||||
void endVisit() override
|
||||
{
|
||||
m_nestingDepth = 0;
|
||||
}
|
||||
void incrementNestingDepth()
|
||||
{
|
||||
++m_nestingDepth;
|
||||
}
|
||||
bool nestingTooDeep()
|
||||
{
|
||||
return m_nestingDepth > s_maxNestingDepth;
|
||||
}
|
||||
void setup() override;
|
||||
std::string visit() override;
|
||||
std::string name() override { return "Block statement generator"; }
|
||||
private:
|
||||
size_t m_nestingDepth;
|
||||
static constexpr unsigned s_maxStatements = 4;
|
||||
static constexpr unsigned s_maxNestingDepth = 3;
|
||||
};
|
||||
|
||||
class SolidityGenerator: public std::enable_shared_from_this<SolidityGenerator>
|
||||
|
Loading…
Reference in New Issue
Block a user