mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add function I/O params.
This commit is contained in:
parent
31ec048f76
commit
bbd451dd16
@ -230,8 +230,52 @@ string FunctionGenerator::visit()
|
|||||||
if (!m_freeFunction)
|
if (!m_freeFunction)
|
||||||
visibility = "public";
|
visibility = "public";
|
||||||
|
|
||||||
|
auto inputType = TypeGenerator{state}.type();
|
||||||
|
state->currentFunctionState()->addInput(pair<string, shared_ptr<SolidityType>>("i1", inputType));
|
||||||
|
string inputParams = inputType->toString() + " i1";
|
||||||
return indentation(state->indentationLevel) +
|
return indentation(state->indentationLevel) +
|
||||||
"function " + name + "() " + visibility + " pure {}\n";
|
"function " + name + "(" + inputParams + ") " + visibility + " pure {}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_ptr<SolidityType> TypeGenerator::type()
|
||||||
|
{
|
||||||
|
switch (typeCategory())
|
||||||
|
{
|
||||||
|
case Type::INTEGER:
|
||||||
|
{
|
||||||
|
IntegerType::Bits b = static_cast<IntegerType::Bits>(
|
||||||
|
state->uRandDist->distributionOneToN(
|
||||||
|
static_cast<size_t>(IntegerType::Bits::B256)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// Choose signed/unsigned type with probability of 1/2 = 0.5
|
||||||
|
bool signedType = state->uRandDist->probable(2);
|
||||||
|
return dynamic_pointer_cast<SolidityType>(make_shared<IntegerType>(b, signedType));
|
||||||
|
}
|
||||||
|
case Type::BOOL:
|
||||||
|
return dynamic_pointer_cast<SolidityType>(make_shared<BoolType>());
|
||||||
|
case Type::FIXEDBYTES:
|
||||||
|
{
|
||||||
|
FixedBytesType::Bytes w = static_cast<FixedBytesType::Bytes>(
|
||||||
|
state->uRandDist->distributionOneToN(
|
||||||
|
static_cast<size_t>(FixedBytesType::Bytes::W32)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return dynamic_pointer_cast<SolidityType>(make_shared<FixedBytesType>(w));
|
||||||
|
}
|
||||||
|
case Type::BYTES:
|
||||||
|
return dynamic_pointer_cast<SolidityType>(make_shared<BytesType>());
|
||||||
|
case Type::ADDRESS:
|
||||||
|
return dynamic_pointer_cast<SolidityType>(make_shared<AddressType>());
|
||||||
|
case Type::FUNCTION:
|
||||||
|
return dynamic_pointer_cast<SolidityType>(make_shared<FunctionType>());
|
||||||
|
case Type::CONTRACT:
|
||||||
|
if (state->sourceUnitState[state->currentPath()]->contractType())
|
||||||
|
return state->sourceUnitState[state->currentPath()]->randomContractType();
|
||||||
|
return dynamic_pointer_cast<SolidityType>(make_shared<BoolType>());
|
||||||
|
default:
|
||||||
|
solAssert(false, "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -243,7 +243,7 @@ struct BytesType: SolidityType
|
|||||||
{
|
{
|
||||||
std::string toString() override
|
std::string toString() override
|
||||||
{
|
{
|
||||||
return "bytes";
|
return "bytes memory";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ struct ContractType: SolidityType
|
|||||||
{}
|
{}
|
||||||
std::string toString() override
|
std::string toString() override
|
||||||
{
|
{
|
||||||
return "type(" + contractName + ")";
|
return name();
|
||||||
}
|
}
|
||||||
std::string name()
|
std::string name()
|
||||||
{
|
{
|
||||||
@ -265,13 +265,23 @@ struct ContractType: SolidityType
|
|||||||
struct FunctionType: SolidityType
|
struct FunctionType: SolidityType
|
||||||
{
|
{
|
||||||
FunctionType() = default;
|
FunctionType() = default;
|
||||||
~FunctionType()
|
~FunctionType() override
|
||||||
{
|
{
|
||||||
inputs.clear();
|
inputs.clear();
|
||||||
outputs.clear();
|
outputs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string toString()
|
void addInput(std::shared_ptr<SolidityType> _input)
|
||||||
|
{
|
||||||
|
inputs.emplace_back(_input);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addOutput(std::shared_ptr<SolidityType> _output)
|
||||||
|
{
|
||||||
|
outputs.emplace_back(_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string toString() override
|
||||||
{
|
{
|
||||||
auto typeString = [](std::vector<std::shared_ptr<SolidityType>>& _types)
|
auto typeString = [](std::vector<std::shared_ptr<SolidityType>>& _types)
|
||||||
{
|
{
|
||||||
@ -286,20 +296,20 @@ struct FunctionType: SolidityType
|
|||||||
return typeStr;
|
return typeStr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string retString = std::string("function ") + "(" + typeString(inputs) + ")";
|
||||||
if (outputs.empty())
|
if (outputs.empty())
|
||||||
return std::string("function (") + typeString(inputs) + ") public pure {}";
|
return retString + " public pure";
|
||||||
else
|
else
|
||||||
return std::string("function (") +
|
return retString + " public pure returns (" + typeString(outputs) + ")";
|
||||||
typeString(inputs) +
|
|
||||||
") public pure returns (" +
|
|
||||||
typeString(outputs) +
|
|
||||||
") {}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<SolidityType>> inputs;
|
std::vector<std::shared_ptr<SolidityType>> inputs;
|
||||||
std::vector<std::shared_ptr<SolidityType>> outputs;
|
std::vector<std::shared_ptr<SolidityType>> outputs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Forward declaration
|
||||||
|
struct TestState;
|
||||||
|
|
||||||
struct SourceState
|
struct SourceState
|
||||||
{
|
{
|
||||||
explicit SourceState(std::shared_ptr<UniformRandomDistribution> _urd):
|
explicit SourceState(std::shared_ptr<UniformRandomDistribution> _urd):
|
||||||
@ -308,7 +318,7 @@ struct SourceState
|
|||||||
{}
|
{}
|
||||||
void addFreeFunction(std::string& _functionName)
|
void addFreeFunction(std::string& _functionName)
|
||||||
{
|
{
|
||||||
exports[std::make_shared<FunctionType>()] = _functionName;
|
exports[std::dynamic_pointer_cast<SolidityType>(std::make_shared<FunctionType>())] = _functionName;
|
||||||
}
|
}
|
||||||
bool freeFunction(std::string const& _functionName)
|
bool freeFunction(std::string const& _functionName)
|
||||||
{
|
{
|
||||||
@ -331,6 +341,18 @@ struct SourceState
|
|||||||
}) | ranges::to<std::vector<std::string>>;
|
}) | ranges::to<std::vector<std::string>>;
|
||||||
return contracts[uRandDist->distributionOneToN(contracts.size()) - 1];
|
return contracts[uRandDist->distributionOneToN(contracts.size()) - 1];
|
||||||
}
|
}
|
||||||
|
std::shared_ptr<SolidityType> randomContractType()
|
||||||
|
{
|
||||||
|
auto contracts = exports |
|
||||||
|
ranges::views::filter([](auto& _item) -> bool {
|
||||||
|
return bool(std::dynamic_pointer_cast<ContractType>(_item.first));
|
||||||
|
}) |
|
||||||
|
ranges::views::transform([](auto& _item) -> std::shared_ptr<SolidityType> {
|
||||||
|
return _item.first;
|
||||||
|
}) |
|
||||||
|
ranges::to<std::vector<std::shared_ptr<SolidityType>>>;
|
||||||
|
return contracts[uRandDist->distributionOneToN(contracts.size()) - 1];
|
||||||
|
}
|
||||||
void addImportedSourcePath(std::string& _sourcePath)
|
void addImportedSourcePath(std::string& _sourcePath)
|
||||||
{
|
{
|
||||||
importedSources.emplace(_sourcePath);
|
importedSources.emplace(_sourcePath);
|
||||||
@ -355,7 +377,26 @@ struct SourceState
|
|||||||
std::map<std::shared_ptr<SolidityType>, std::string> exports;
|
std::map<std::shared_ptr<SolidityType>, std::string> exports;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionState {};
|
struct FunctionState
|
||||||
|
{
|
||||||
|
FunctionState() = default;
|
||||||
|
~FunctionState()
|
||||||
|
{
|
||||||
|
inputs.clear();
|
||||||
|
outputs.clear();
|
||||||
|
}
|
||||||
|
void addInput(std::pair<std::string, std::shared_ptr<SolidityType>> _input)
|
||||||
|
{
|
||||||
|
inputs.emplace(_input);
|
||||||
|
}
|
||||||
|
void addOutput(std::pair<std::string, std::shared_ptr<SolidityType>> _output)
|
||||||
|
{
|
||||||
|
outputs.emplace(_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::shared_ptr<SolidityType>> inputs;
|
||||||
|
std::map<std::string, std::shared_ptr<SolidityType>> outputs;
|
||||||
|
};
|
||||||
|
|
||||||
struct TestState
|
struct TestState
|
||||||
{
|
{
|
||||||
@ -393,6 +434,10 @@ struct TestState
|
|||||||
functionState.emplace(_name, std::make_shared<FunctionState>());
|
functionState.emplace(_name, std::make_shared<FunctionState>());
|
||||||
currentFunction = _name;
|
currentFunction = _name;
|
||||||
}
|
}
|
||||||
|
std::shared_ptr<FunctionState> currentFunctionState()
|
||||||
|
{
|
||||||
|
return functionState[currentFunction];
|
||||||
|
}
|
||||||
/// Returns true if @name sourceUnitPaths is empty,
|
/// Returns true if @name sourceUnitPaths is empty,
|
||||||
/// false otherwise.
|
/// false otherwise.
|
||||||
[[nodiscard]] bool empty() const
|
[[nodiscard]] bool empty() const
|
||||||
@ -502,6 +547,33 @@ struct TestState
|
|||||||
std::string const functionPrefix = "f";
|
std::string const functionPrefix = "f";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TypeGenerator
|
||||||
|
{
|
||||||
|
TypeGenerator(std::shared_ptr<TestState> _state): state(std::move(_state))
|
||||||
|
{}
|
||||||
|
|
||||||
|
enum class Type: size_t
|
||||||
|
{
|
||||||
|
INTEGER = 1,
|
||||||
|
BOOL,
|
||||||
|
FIXEDBYTES,
|
||||||
|
BYTES,
|
||||||
|
ADDRESS,
|
||||||
|
FUNCTION,
|
||||||
|
CONTRACT,
|
||||||
|
TYPEMAX
|
||||||
|
};
|
||||||
|
|
||||||
|
std::shared_ptr<SolidityType> type();
|
||||||
|
|
||||||
|
Type typeCategory()
|
||||||
|
{
|
||||||
|
return static_cast<Type>(state->uRandDist->distributionOneToN(static_cast<size_t>(Type::TYPEMAX) - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<TestState> state;
|
||||||
|
};
|
||||||
|
|
||||||
struct GeneratorBase
|
struct GeneratorBase
|
||||||
{
|
{
|
||||||
explicit GeneratorBase(std::shared_ptr<SolidityGenerator> _mutator);
|
explicit GeneratorBase(std::shared_ptr<SolidityGenerator> _mutator);
|
||||||
|
Loading…
Reference in New Issue
Block a user