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) \
|
#define GENERATORLIST(MACRO, SEP, ENDSEP) \
|
||||||
|
MACRO(AssignmentStmtGenerator) SEP \
|
||||||
MACRO(BlockStmtGenerator) SEP \
|
MACRO(BlockStmtGenerator) SEP \
|
||||||
MACRO(ContractGenerator) SEP \
|
MACRO(ContractGenerator) SEP \
|
||||||
MACRO(FunctionGenerator) SEP \
|
MACRO(FunctionGenerator) SEP \
|
||||||
|
@ -265,9 +265,51 @@ string FunctionState::params(Params _p)
|
|||||||
return "(" + boost::algorithm::join(params, ",") + ")";
|
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()
|
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()
|
void FunctionGenerator::setup()
|
||||||
@ -303,10 +345,54 @@ string FunctionGenerator::visit()
|
|||||||
if (!state->currentFunctionState()->outputs.empty())
|
if (!state->currentFunctionState()->outputs.empty())
|
||||||
function << " returns"
|
function << " returns"
|
||||||
<< state->currentFunctionState()->params(FunctionState::Params::OUTPUT);
|
<< state->currentFunctionState()->params(FunctionState::Params::OUTPUT);
|
||||||
function << generator<BlockStmtGenerator>()->visit();
|
function << "\n" << generator<BlockStmtGenerator>()->visit();
|
||||||
return function.str();
|
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)
|
optional<SolidityTypePtr> TypeProvider::type(SolidityTypePtr _type)
|
||||||
{
|
{
|
||||||
vector<SolidityTypePtr> matchingTypes = state->currentFunctionState()->inputs |
|
vector<SolidityTypePtr> matchingTypes = state->currentFunctionState()->inputs |
|
||||||
|
@ -619,13 +619,15 @@ struct ExpressionGenerator
|
|||||||
ExpressionGenerator(std::shared_ptr<TestState> _state): state(std::move(_state))
|
ExpressionGenerator(std::shared_ptr<TestState> _state): state(std::move(_state))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
enum class Expr: size_t
|
enum class LValueExpr: size_t
|
||||||
{
|
{
|
||||||
VARREF = 1,
|
VARREF = 1,
|
||||||
TYPEMAX
|
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;
|
std::shared_ptr<TestState> state;
|
||||||
};
|
};
|
||||||
@ -807,19 +809,47 @@ public:
|
|||||||
explicit StatementGenerator(std::shared_ptr<SolidityGenerator> _mutator):
|
explicit StatementGenerator(std::shared_ptr<SolidityGenerator> _mutator):
|
||||||
GeneratorBase(std::move(_mutator))
|
GeneratorBase(std::move(_mutator))
|
||||||
{}
|
{}
|
||||||
void setup() override {}
|
void setup() override;
|
||||||
std::string visit() override { return {}; }
|
std::string visit() override;
|
||||||
std::string name() override { return "Statement generator"; }
|
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
|
class BlockStmtGenerator: public GeneratorBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit BlockStmtGenerator(std::shared_ptr<SolidityGenerator> _mutator):
|
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 visit() override;
|
||||||
std::string name() override { return "Block statement generator"; }
|
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>
|
class SolidityGenerator: public std::enable_shared_from_this<SolidityGenerator>
|
||||||
|
Loading…
Reference in New Issue
Block a user