[isoltest] Add return-type for builtins.

This commit is contained in:
Alexander Arlt 2021-03-04 18:15:17 -05:00
parent ae09ac018a
commit 68fe4d2eeb
4 changed files with 44 additions and 17 deletions

View File

@ -14,6 +14,7 @@
#include <test/libsolidity/SemanticTest.h>
#include <libsolidity/ast/TypeProvider.h>
#include <libsolutil/Whiskers.h>
#include <libyul/Exceptions.h>
#include <test/Common.h>
@ -112,7 +113,8 @@ SemanticTest::SemanticTest(string const& _filename, langutil::EVMVersion _evmVer
void SemanticTest::initializeBuiltins()
{
m_builtins["storage_empty"] = [this](FunctionCall const& _call) -> std::optional<bytes>
m_builtins["storage_empty"].returnType = TypeProvider::boolean();
m_builtins["storage_empty"].function = [this](FunctionCall const& _call) -> std::optional<bytes>
{
soltestAssert(_call.arguments.parameters.empty(), "No arguments expected.");
return toBigEndian(u256(storageEmpty(m_contractAddress) ? 1 : 0));
@ -217,7 +219,7 @@ TestCase::TestResult SemanticTest::runTest(
output = callLowLevel(test.call().arguments.rawBytes(), test.call().value.value);
else if (test.call().kind == FunctionCall::Kind::Builtin)
{
std::optional<bytes> builtinOutput = m_builtins.at(test.call().signature)(test.call());
std::optional<bytes> builtinOutput = m_builtins.at(test.call().signature).function(test.call());
if (builtinOutput.has_value())
{
m_transactionSuccessful = true;

View File

@ -19,6 +19,11 @@
#include <test/ExecutionFramework.h>
namespace solidity::frontend
{
class Type;
}
namespace solidity::frontend::test
{
@ -297,8 +302,13 @@ struct FunctionCall
/// Marks this function call as "short-handed", meaning
/// no `->` declared.
bool omitsArrow = true;
solidity::frontend::Type const* builtinReturnType = nullptr;
};
using Builtin = std::function<std::optional<bytes>(FunctionCall const&)>;
struct Builtin
{
std::function<std::optional<bytes>(FunctionCall const&)> function;
solidity::frontend::Type const* returnType;
};
}

View File

@ -92,7 +92,10 @@ vector<solidity::frontend::test::FunctionCall> TestFileParser::parseFunctionCall
if (lowLevelCall)
call.kind = FunctionCall::Kind::LowLevel;
else if (isBuiltinFunction(call.signature))
{
call.kind = FunctionCall::Kind::Builtin;
call.builtinReturnType = m_builtins.at(call.signature).returnType;
}
if (accept(Token::Comma, true))
call.value = parseFunctionCallValue();

View File

@ -14,6 +14,7 @@
#include <test/libsolidity/util/TestFunctionCall.h>
#include <libsolidity/ast/TypeProvider.h>
#include <test/libsolidity/util/BytesUtils.h>
#include <test/libsolidity/util/ContractABIUtils.h>
@ -30,8 +31,6 @@ using namespace solidity::util;
using namespace solidity::frontend::test;
using namespace std;
using Token = soltest::Token;
string TestFunctionCall::format(
ErrorReporter& _errorReporter,
string const& _linePrefix,
@ -46,14 +45,14 @@ string TestFunctionCall::format(
auto formatOutput = [&](bool const _singleLine)
{
string ws = " ";
string arrow = formatToken(Token::Arrow);
string colon = formatToken(Token::Colon);
string comma = formatToken(Token::Comma);
string comment = formatToken(Token::Comment);
string ether = formatToken(Token::Ether);
string wei = formatToken(Token::Wei);
string newline = formatToken(Token::Newline);
string failure = formatToken(Token::Failure);
string arrow = formatToken(soltest::Token::Arrow);
string colon = formatToken(soltest::Token::Colon);
string comma = formatToken(soltest::Token::Comma);
string comment = formatToken(soltest::Token::Comment);
string ether = formatToken(soltest::Token::Ether);
string wei = formatToken(soltest::Token::Wei);
string newline = formatToken(soltest::Token::Newline);
string failure = formatToken(soltest::Token::Failure);
if (m_call.kind == FunctionCall::Kind::Library)
{
@ -247,10 +246,23 @@ string TestFunctionCall::formatBytesParameters(
}
else
{
ParameterList defaultParameters = ContractABIUtils::defaultParameters((_bytes.size() + 31) / 32);
if (call().kind == FunctionCall::Kind::Builtin && call().builtinReturnType)
{
if (call().builtinReturnType == TypeProvider::boolean())
{
if (util::toHex(_bytes) == "0000000000000000000000000000000000000000000000000000000000000000")
os << "false";
else
os << "true";
}
}
else
{
ParameterList defaultParameters = ContractABIUtils::defaultParameters((_bytes.size() + 31) / 32);
ContractABIUtils::overwriteParameters(_errorReporter, defaultParameters, _parameters);
os << BytesUtils::formatBytesRange(_bytes, defaultParameters, _highlight);
ContractABIUtils::overwriteParameters(_errorReporter, defaultParameters, _parameters);
os << BytesUtils::formatBytesRange(_bytes, defaultParameters, _highlight);
}
}
return os.str();
}
@ -266,7 +278,7 @@ string TestFunctionCall::formatFailure(
{
stringstream os;
os << formatToken(Token::Failure);
os << formatToken(soltest::Token::Failure);
if (!_output.empty())
os << ", ";