From de34f7712d482ddf834247e311385dd492c4bb89 Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Wed, 3 Jul 2019 21:37:55 +0200 Subject: [PATCH 1/2] Separates types and conversion functions in soltest. --- test/libsolidity/util/BytesUtils.cpp | 165 ++++++++++++++ test/libsolidity/util/BytesUtils.h | 84 +++++++ test/libsolidity/util/ContractABIUtils.cpp | 87 ++++++++ test/libsolidity/util/ContractABIUtils.h | 59 +++++ test/libsolidity/util/SoltestTypes.h | 247 +++++++++++++++++++++ test/libsolidity/util/TestFileParser.cpp | 66 +----- test/libsolidity/util/TestFileParser.h | 237 +------------------- test/libsolidity/util/TestFunctionCall.cpp | 110 ++------- test/libsolidity/util/TestFunctionCall.h | 8 + test/tools/CMakeLists.txt | 2 + 10 files changed, 679 insertions(+), 386 deletions(-) create mode 100644 test/libsolidity/util/BytesUtils.cpp create mode 100644 test/libsolidity/util/BytesUtils.h create mode 100644 test/libsolidity/util/ContractABIUtils.cpp create mode 100644 test/libsolidity/util/ContractABIUtils.h create mode 100644 test/libsolidity/util/SoltestTypes.h diff --git a/test/libsolidity/util/BytesUtils.cpp b/test/libsolidity/util/BytesUtils.cpp new file mode 100644 index 000000000..1659324de --- /dev/null +++ b/test/libsolidity/util/BytesUtils.cpp @@ -0,0 +1,165 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ + +#include + +#include + +#include + +#include +#include +#include +#include + +using namespace dev; +using namespace langutil; +using namespace solidity; +using namespace dev::solidity::test; +using namespace std; +using namespace soltest; + +bytes BytesUtils::convertBoolean(string const& _literal) +{ + if (_literal == "true") + return bytes{true}; + else if (_literal == "false") + return bytes{false}; + else + throw Error(Error::Type::ParserError, "Boolean literal invalid."); +} + +bytes BytesUtils::convertNumber(string const& _literal) +{ + try + { + return toCompactBigEndian(u256{_literal}); + } + catch (std::exception const&) + { + throw Error(Error::Type::ParserError, "Number encoding invalid."); + } +} + +bytes BytesUtils::convertHexNumber(string const& _literal) +{ + try + { + if (_literal.size() % 2) + throw Error(Error::Type::ParserError, "Hex number encoding invalid."); + else + return fromHex(_literal); + } + catch (std::exception const&) + { + throw Error(Error::Type::ParserError, "Hex number encoding invalid."); + } +} + +bytes BytesUtils::convertString(string const& _literal) +{ + try + { + return asBytes(_literal); + } + catch (std::exception const&) + { + throw Error(Error::Type::ParserError, "String encoding invalid."); + } +} + +string BytesUtils::formatUnsigned(bytes const& _bytes) const +{ + stringstream os; + + if (*_bytes.begin() & 0x80) + os << u2s(fromBigEndian(_bytes)); + else + os << fromBigEndian(_bytes); + + return os.str(); +} + +string BytesUtils::formatSigned(bytes const& _bytes) const +{ + stringstream os; + + if (*_bytes.begin() & 0x80) + os << u2s(fromBigEndian(_bytes)); + else + os << fromBigEndian(_bytes); + + return os.str(); +} + +string BytesUtils::formatBoolean(bytes const& _bytes) const +{ + stringstream os; + u256 result = fromBigEndian(_bytes); + + if (result == 0) + os << "false"; + else if (result == 1) + os << "true"; + else + os << result; + + return os.str(); +} + +string BytesUtils::formatHex(bytes const& _bytes) const +{ + stringstream os; + + string hex{toHex(_bytes, HexPrefix::Add)}; + boost::algorithm::replace_all(hex, "00", ""); + os << hex; + + return os.str(); +} + +string BytesUtils::formatHexString(bytes const& _bytes) const +{ + stringstream os; + + os << "hex\"" << toHex(_bytes) << "\""; + + return os.str(); +} + +string BytesUtils::formatString(bytes const& _bytes) const +{ + stringstream os; + + os << "\""; + bool expectZeros = false; + for (auto const& v: _bytes) + { + if (expectZeros && v != 0) + return {}; + if (v == 0) expectZeros = true; + else + { + if (!isprint(v) || v == '"') + return {}; + os << v; + } + } + os << "\""; + + return os.str(); +} diff --git a/test/libsolidity/util/BytesUtils.h b/test/libsolidity/util/BytesUtils.h new file mode 100644 index 000000000..4bcf1a5b4 --- /dev/null +++ b/test/libsolidity/util/BytesUtils.h @@ -0,0 +1,84 @@ +/* + This file is part of solidity. + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ + +#pragma once + +#include + +#include + +namespace dev +{ +namespace solidity +{ +namespace test +{ + +/** + * Utility class that aids conversions from parsed strings to an + * isoltest-internal, ABI-based bytes representation and vice-versa. + */ +class BytesUtils +{ +public: + /// Tries to convert \param _literal to an unpadded `bytes` + /// representation of the boolean number literal. Throws if conversion fails. + bytes convertBoolean(std::string const& _literal); + + /// Tries to convert \param _literal to an unpadded `bytes` + /// representation of the decimal number literal. Throws if conversion fails. + bytes convertNumber(std::string const& _literal); + + /// Tries to convert \param _literal to an unpadded `bytes` + /// representation of the hex literal. Throws if conversion fails. + bytes convertHexNumber(std::string const& _literal); + + /// Tries to convert \param _literal to an unpadded `bytes` + /// representation of the string literal. Throws if conversion fails. + bytes convertString(std::string const& _literal); + + /// Converts \param _bytes to a soltest-compliant and human-readable + /// string representation of a byte array which is assumed to hold + /// an unsigned value. + std::string formatUnsigned(bytes const& _bytes) const; + + /// Converts \param _bytes to a soltest-compliant and human-readable + /// string representation of a byte array which is assumed to hold + /// a signed value. + std::string formatSigned(bytes const& _bytes) const; + + /// Converts \param _bytes to a soltest-compliant and human-readable + /// string representation of a byte array which is assumed to hold + /// a boolean value. + std::string formatBoolean(bytes const& _bytes) const; + + /// Converts \param _bytes to a soltest-compliant and human-readable + /// string representation of a byte array which is assumed to hold + /// a hex value. + std::string formatHex(bytes const& _bytes) const; + + /// Converts \param _bytes to a soltest-compliant and human-readable + /// string representation of a byte array which is assumed to hold + /// a hexString value. + std::string formatHexString(bytes const& _bytes) const; + + /// Converts \param _bytes to a soltest-compliant and human-readable + /// string representation of a byte array which is assumed to hold + /// a string value. + std::string formatString(bytes const& _bytes) const; +}; + +} +} +} diff --git a/test/libsolidity/util/ContractABIUtils.cpp b/test/libsolidity/util/ContractABIUtils.cpp new file mode 100644 index 000000000..ec9cbcba0 --- /dev/null +++ b/test/libsolidity/util/ContractABIUtils.cpp @@ -0,0 +1,87 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ + +#include + +#include + +#include + +#include +#include +#include +#include + +using namespace dev; +using namespace langutil; +using namespace solidity; +using namespace dev::solidity::test; +using namespace std; +using namespace soltest; + +dev::solidity::test::ParameterList ContractABIUtils::parametersFromJson( + Json::Value const& _contractABI, + string const& _functionName +) const +{ + ParameterList abiParams; + for (auto const& function: _contractABI) + if (function["name"] == _functionName) + for (auto const& output: function["outputs"]) + { + auto types = fromTypeName(output["type"].asString()); + for (auto const& type: types) + abiParams.push_back(Parameter{bytes(), "", type, FormatInfo{}}); + } + + return abiParams; +} + +std::vector ContractABIUtils::fromTypeName(string const& _type) const +{ + static regex s_boolType{"(bool)"}; + static regex s_uintType{"(uint\\d*)"}; + static regex s_intType{"(int\\d*)"}; + static regex s_bytesType{"(bytes\\d+)"}; + static regex s_dynBytesType{"(\\bbytes\\b)"}; + static regex s_stringType{"(string)"}; + + vector abiTypes; + if (regex_match(_type, s_boolType)) + abiTypes.push_back(ABIType{ABIType::Boolean, ABIType::AlignRight, 32}); + else if (regex_match(_type, s_uintType)) + abiTypes.push_back(ABIType{ABIType::UnsignedDec, ABIType::AlignRight, 32}); + else if (regex_match(_type, s_intType)) + abiTypes.push_back(ABIType{ABIType::SignedDec, ABIType::AlignRight, 32}); + else if (regex_match(_type, s_bytesType)) + abiTypes.push_back(ABIType{ABIType::Hex, ABIType::AlignRight, 32}); + else if (regex_match(_type, s_dynBytesType)) + { + abiTypes.push_back(ABIType{ABIType::UnsignedDec, ABIType::AlignRight, 32}); + abiTypes.push_back(ABIType{ABIType::UnsignedDec, ABIType::AlignRight, 32}); + abiTypes.push_back(ABIType{ABIType::HexString, ABIType::AlignLeft, 32}); + } + else if (regex_match(_type, s_stringType)) + { + abiTypes.push_back(ABIType{ABIType::UnsignedDec, ABIType::AlignRight, 32}); + abiTypes.push_back(ABIType{ABIType::UnsignedDec, ABIType::AlignRight, 32}); + abiTypes.push_back(ABIType{ABIType::String, ABIType::AlignLeft, 32}); + } + else + abiTypes.push_back(ABIType{ABIType::None, ABIType::AlignRight, 0}); + return abiTypes; +} diff --git a/test/libsolidity/util/ContractABIUtils.h b/test/libsolidity/util/ContractABIUtils.h new file mode 100644 index 000000000..cafd63bac --- /dev/null +++ b/test/libsolidity/util/ContractABIUtils.h @@ -0,0 +1,59 @@ +/* + This file is part of solidity. + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ + +#pragma once + +#include + +#include + +#include + +namespace dev +{ +namespace solidity +{ +namespace test +{ + +/** + * Utility class that aids conversions from contract ABI types stored in a + * Json value to the internal ABIType representation of isoltest. + */ +class ContractABIUtils +{ +public: + /// Parses and translates Solidity's ABI types as Json string into + /// a list of internal type representations of isoltest. + ParameterList parametersFromJson( + Json::Value const& _contractABI, + std::string const& _functionName + ) const; + +private: + /// Parses and translates a single type and returns a list of + /// internal type representations of isoltest. + /// Types defined by the ABI will translate to ABITypes + /// as follows: + /// `bool` -> [`Boolean`] + /// `uint` -> [`Unsigned`] + /// `string` -> [`Unsigned`, `Unsigned`, `String`] + /// `bytes` -> [`Unsigned`, `Unsigned`, `HexString`] + /// ... + std::vector fromTypeName(std::string const& _type) const; +}; + +} +} +} diff --git a/test/libsolidity/util/SoltestTypes.h b/test/libsolidity/util/SoltestTypes.h new file mode 100644 index 000000000..9eba08869 --- /dev/null +++ b/test/libsolidity/util/SoltestTypes.h @@ -0,0 +1,247 @@ +/* + This file is part of solidity. + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ + +#pragma once + +#include +#include + +namespace dev +{ +namespace solidity +{ +namespace test +{ + +/** + * All soltest tokens. + */ +#define SOLT_TOKEN_LIST(T, K) \ + T(Unknown, "unknown", 0) \ + T(Invalid, "invalid", 0) \ + T(EOS, "EOS", 0) \ + T(Whitespace, "_", 0) \ + /* punctuations */ \ + T(LParen, "(", 0) \ + T(RParen, ")", 0) \ + T(LBrack, "[", 0) \ + T(RBrack, "]", 0) \ + T(LBrace, "{", 0) \ + T(RBrace, "}", 0) \ + T(Sub, "-", 0) \ + T(Colon, ":", 0) \ + T(Comma, ",", 0) \ + T(Period, ".", 0) \ + T(Arrow, "->", 0) \ + T(Newline, "//", 0) \ + /* Literals & identifier */ \ + T(Comment, "#", 0) \ + T(Number, "number", 0) \ + T(HexNumber, "hex_number", 0) \ + T(String, "string", 0) \ + T(Identifier, "identifier", 0) \ + /* type keywords */ \ + K(Ether, "ether", 0) \ + K(Hex, "hex", 0) \ + K(Boolean, "boolean", 0) \ + /* special keywords */ \ + K(Left, "left", 0) \ + K(Right, "right", 0) \ + K(Failure, "FAILURE", 0) \ + +namespace soltest +{ + enum class Token : unsigned int { + #define T(name, string, precedence) name, + SOLT_TOKEN_LIST(T, T) + NUM_TOKENS + #undef T + }; + + /// Prints a friendly string representation of \param _token. + inline std::string formatToken(Token _token) + { + switch (_token) + { + #define T(name, string, precedence) case Token::name: return string; + SOLT_TOKEN_LIST(T, T) + #undef T + default: // Token::NUM_TOKENS: + return ""; + } + } +} + +/** + * The purpose of the ABI type is the storage of type information + * retrieved while parsing a test. This information is used + * for the conversion of human-readable function arguments and + * return values to `bytes` and vice-versa. + * Defaults to None, a 0-byte representation. 0-bytes + * can also be interpreted as Failure, which means + * either a REVERT or another EVM failure. + */ +struct ABIType +{ + enum Type + { + None, + Failure, + Boolean, + UnsignedDec, + SignedDec, + Hex, + HexString, + String + }; + enum Align + { + AlignLeft, + AlignRight, + AlignNone, + }; + Type type = ABIType::None; + Align align = ABIType::AlignRight; + size_t size = 0; + bool alignDeclared = false; +}; + +/** + * Helper that can hold format information retrieved + * while scanning through a parameter list in soltest. + */ +struct FormatInfo +{ + bool newline = false; +}; + +/** + * Parameter abstraction used for the encoding and decoding of + * function parameter and expectation / return value lists. + * A parameter list is usually a comma-separated list of literals. + * It should not be possible to call create a parameter holding + * an identifier, but if so, the ABI type would be invalid. + */ +struct Parameter +{ + /// ABI encoded / decoded `bytes` of values. + /// These `bytes` are used to pass values to function calls + /// and also to store expected return vales. These are + /// compared to the actual result of a function call + /// and used for validating it. + bytes rawBytes; + /// Stores the raw string representation of this parameter. + /// Used to print the unformatted arguments of a function call. + std::string rawString; + /// Types that were used to encode `rawBytes`. Expectations + /// are usually comma separated literals. Their type is auto- + /// detected and retained in order to format them later on. + ABIType abiType; + /// Format info attached to the parameter. It handles newlines given + /// in the declaration of it. + FormatInfo format; +}; +using ParameterList = std::vector; + +/** + * Represents the expected result of a function call after it has been executed. This may be a single + * return value or a comma-separated list of return values. It also contains the detected input + * formats used to convert the values to `bytes` needed for the comparison with the actual result + * of a call. In addition to that, it also stores the expected transaction status. + * An optional comment can be assigned. + */ +struct FunctionCallExpectations +{ + /// Representation of the comma-separated (or empty) list of expected result values + /// attached to the function call object. It is checked against the actual result of + /// a function call when used in test framework. + ParameterList result; + /// Expected status of the transaction. It can be either + /// a REVERT or a different EVM failure (e.g. out-of-gas). + bool failure = true; + /// A Comment that can be attached to the expectations, + /// that is retained and can be displayed. + std::string comment; + /// ABI encoded `bytes` of parsed expected return values. It is checked + /// against the actual result of a function call when used in test framework. + bytes rawBytes() const + { + bytes raw; + for (auto const& param: result) + raw += param.rawBytes; + return raw; + } +}; + +/** + * Represents the arguments passed to a function call. This can be a single + * argument or a comma-separated list of arguments. It also contains the detected input + * formats used to convert the arguments to `bytes` needed for the call. + * An optional comment can be assigned. + */ +struct FunctionCallArgs +{ + /// Types that were used to encode `rawBytes`. Parameters + /// are usually comma separated literals. Their type is auto- + /// detected and retained in order to format them later on. + ParameterList parameters; + /// A Comment that can be attached to the expectations, + /// that is retained and can be displayed. + std::string comment; + /// ABI encoded `bytes` of parsed parameters. These `bytes` + /// passed to the function call. + bytes rawBytes() const + { + bytes raw; + for (auto const& param: parameters) + raw += param.rawBytes; + return raw; + } +}; + +/** + * Represents a function call read from an input stream. It contains the signature, the + * arguments, an optional ether value and an expected execution result. + */ +struct FunctionCall +{ + /// Signature of the function call, e.g. `f(uint256, uint256)`. + std::string signature; + /// Optional `ether` value that can be send with the call. + u256 value; + /// Object that holds all function parameters in their `bytes` + /// representations given by the contract ABI. + FunctionCallArgs arguments; + /// Object that holds all function call expectation in + /// their `bytes` representations given by the contract ABI. + /// They are checked against the actual results and their + /// `bytes` representation, as well as the transaction status. + FunctionCallExpectations expectations; + /// single / multi-line mode will be detected as follows: + /// every newline (//) in source results in a function call + /// that has its display mode set to multi-mode. Function and + /// result parameter lists are an exception: a single parameter + /// stores a format information that contains a newline definition. + enum DisplayMode { + SingleLine, + MultiLine + }; + DisplayMode displayMode = DisplayMode::SingleLine; + /// Marks this function call as the constructor. + bool isConstructor = false; +}; + +} +} +} diff --git a/test/libsolidity/util/TestFileParser.cpp b/test/libsolidity/util/TestFileParser.cpp index 4f61f6911..05f883be5 100644 --- a/test/libsolidity/util/TestFileParser.cpp +++ b/test/libsolidity/util/TestFileParser.cpp @@ -16,12 +16,17 @@ */ #include + +#include #include + #include + #include #include #include #include + #include #include #include @@ -242,10 +247,12 @@ Parameter TestFileParser::parseParameter() Parameter parameter; if (accept(Token::Newline, true)) parameter.format.newline = true; + auto literal = parseABITypeLiteral(); parameter.rawBytes = get<0>(literal); parameter.abiType = get<1>(literal); parameter.rawString = get<2>(literal); + return parameter; } @@ -286,7 +293,7 @@ tuple TestFileParser::parseABITypeLiteral() abiType = ABIType{ABIType::Boolean, ABIType::AlignRight, 32}; string parsed = parseBoolean(); rawString += parsed; - result = applyAlign(alignment, abiType, convertBoolean(parsed)); + result = applyAlign(alignment, abiType, BytesUtils().convertBoolean(parsed)); } else if (accept(Token::HexNumber)) { @@ -295,7 +302,7 @@ tuple TestFileParser::parseABITypeLiteral() abiType = ABIType{ABIType::Hex, ABIType::AlignRight, 32}; string parsed = parseHexNumber(); rawString += parsed; - result = applyAlign(alignment, abiType, convertHexNumber(parsed)); + result = applyAlign(alignment, abiType, BytesUtils().convertHexNumber(parsed)); } else if (accept(Token::Hex, true)) { @@ -305,7 +312,7 @@ tuple TestFileParser::parseABITypeLiteral() throw Error(Error::Type::ParserError, "Hex string literals cannot be aligned or padded."); string parsed = parseString(); rawString += "hex\"" + parsed + "\""; - result = convertHexNumber(parsed); + result = BytesUtils().convertHexNumber(parsed); abiType = ABIType{ABIType::HexString, ABIType::AlignNone, result.size()}; } else if (accept(Token::String)) @@ -317,7 +324,7 @@ tuple TestFileParser::parseABITypeLiteral() abiType = ABIType{ABIType::String, ABIType::AlignLeft, 32}; string parsed = parseString(); rawString += "\"" + parsed + "\""; - result = applyAlign(DeclaredAlignment::Left, abiType, convertString(parsed)); + result = applyAlign(DeclaredAlignment::Left, abiType, BytesUtils().convertString(parsed)); } else if (accept(Token::Number)) { @@ -327,7 +334,7 @@ tuple TestFileParser::parseABITypeLiteral() rawString += parsed; if (isSigned) parsed = "-" + parsed; - result = applyAlign(alignment, abiType, convertNumber(parsed)); + result = applyAlign(alignment, abiType, BytesUtils().convertNumber(parsed)); } else if (accept(Token::Failure, true)) { @@ -426,55 +433,6 @@ string TestFileParser::parseString() return literal; } -bytes TestFileParser::convertBoolean(string const& _literal) -{ - if (_literal == "true") - return bytes{true}; - else if (_literal == "false") - return bytes{false}; - else - throw Error(Error::Type::ParserError, "Boolean literal invalid."); -} - -bytes TestFileParser::convertNumber(string const& _literal) -{ - try - { - return toCompactBigEndian(u256{_literal}); - } - catch (std::exception const&) - { - throw Error(Error::Type::ParserError, "Number encoding invalid."); - } -} - -bytes TestFileParser::convertHexNumber(string const& _literal) -{ - try - { - if (_literal.size() % 2) - throw Error(Error::Type::ParserError, "Hex number encoding invalid."); - else - return fromHex(_literal); - } - catch (std::exception const&) - { - throw Error(Error::Type::ParserError, "Hex number encoding invalid."); - } -} - -bytes TestFileParser::convertString(string const& _literal) -{ - try - { - return asBytes(_literal); - } - catch (std::exception const&) - { - throw Error(Error::Type::ParserError, "String encoding invalid."); - } -} - void TestFileParser::Scanner::readStream(istream& _stream) { std::string line; diff --git a/test/libsolidity/util/TestFileParser.h b/test/libsolidity/util/TestFileParser.h index ea948a9b7..2eb2b793f 100644 --- a/test/libsolidity/util/TestFileParser.h +++ b/test/libsolidity/util/TestFileParser.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -33,226 +34,6 @@ namespace solidity namespace test { -/** - * All soltest tokens. - */ -#define SOLT_TOKEN_LIST(T, K) \ - T(Unknown, "unknown", 0) \ - T(Invalid, "invalid", 0) \ - T(EOS, "EOS", 0) \ - T(Whitespace, "_", 0) \ - /* punctuations */ \ - T(LParen, "(", 0) \ - T(RParen, ")", 0) \ - T(LBrack, "[", 0) \ - T(RBrack, "]", 0) \ - T(LBrace, "{", 0) \ - T(RBrace, "}", 0) \ - T(Sub, "-", 0) \ - T(Colon, ":", 0) \ - T(Comma, ",", 0) \ - T(Period, ".", 0) \ - T(Arrow, "->", 0) \ - T(Newline, "//", 0) \ - /* Literals & identifier */ \ - T(Comment, "#", 0) \ - T(Number, "number", 0) \ - T(HexNumber, "hex_number", 0) \ - T(String, "string", 0) \ - T(Identifier, "identifier", 0) \ - /* type keywords */ \ - K(Ether, "ether", 0) \ - K(Hex, "hex", 0) \ - K(Boolean, "boolean", 0) \ - /* special keywords */ \ - K(Left, "left", 0) \ - K(Right, "right", 0) \ - K(Failure, "FAILURE", 0) \ - -namespace soltest -{ - enum class Token : unsigned int { - #define T(name, string, precedence) name, - SOLT_TOKEN_LIST(T, T) - NUM_TOKENS - #undef T - }; - - /// Prints a friendly string representation of \param _token. - inline std::string formatToken(Token _token) - { - switch (_token) - { - #define T(name, string, precedence) case Token::name: return string; - SOLT_TOKEN_LIST(T, T) - #undef T - default: // Token::NUM_TOKENS: - return ""; - } - } -} - - - -/** - * The purpose of the ABI type is the storage of type information - * retrieved while parsing a test. This information is used - * for the conversion of human-readable function arguments and - * return values to `bytes` and vice-versa. - * Defaults to None, a 0-byte representation. 0-bytes - * can also be interpreted as Failure, which means - * either a REVERT or another EVM failure. - */ -struct ABIType -{ - enum Type - { - None, - Failure, - Boolean, - UnsignedDec, - SignedDec, - Hex, - HexString, - String - }; - enum Align - { - AlignLeft, - AlignRight, - AlignNone, - }; - Type type = ABIType::None; - Align align = ABIType::AlignRight; - size_t size = 0; - bool alignDeclared = false; -}; - -/** - * Helper that can hold format information retrieved - * while scanning through a parameter list in soltest. - */ -struct FormatInfo -{ - bool newline = false; -}; - -/** - * Parameter abstraction used for the encoding and decoding of - * function parameter and expectation / return value lists. - * A parameter list is usually a comma-separated list of literals. - * It should not be possible to call create a parameter holding - * an identifier, but if so, the ABI type would be invalid. - */ -struct Parameter -{ - /// ABI encoded / decoded `bytes` of values. - /// These `bytes` are used to pass values to function calls - /// and also to store expected return vales. These are - /// compared to the actual result of a function call - /// and used for validating it. - bytes rawBytes; - /// Stores the raw string representation of this parameter. - /// Used to print the unformatted arguments of a function call. - std::string rawString; - /// Types that were used to encode `rawBytes`. Expectations - /// are usually comma separated literals. Their type is auto- - /// detected and retained in order to format them later on. - ABIType abiType; - /// Format info attached to the parameter. It handles newlines given - /// in the declaration of it. - FormatInfo format; -}; -using ParameterList = std::vector; - -/** - * Represents the expected result of a function call after it has been executed. This may be a single - * return value or a comma-separated list of return values. It also contains the detected input - * formats used to convert the values to `bytes` needed for the comparison with the actual result - * of a call. In addition to that, it also stores the expected transaction status. - * An optional comment can be assigned. - */ -struct FunctionCallExpectations -{ - /// Representation of the comma-separated (or empty) list of expected result values - /// attached to the function call object. It is checked against the actual result of - /// a function call when used in test framework. - ParameterList result; - /// Expected status of the transaction. It can be either - /// a REVERT or a different EVM failure (e.g. out-of-gas). - bool failure = true; - /// A Comment that can be attached to the expectations, - /// that is retained and can be displayed. - std::string comment; - /// ABI encoded `bytes` of parsed expected return values. It is checked - /// against the actual result of a function call when used in test framework. - bytes rawBytes() const - { - bytes raw; - for (auto const& param: result) - raw += param.rawBytes; - return raw; - } -}; - -/** - * Represents the arguments passed to a function call. This can be a single - * argument or a comma-separated list of arguments. It also contains the detected input - * formats used to convert the arguments to `bytes` needed for the call. - * An optional comment can be assigned. - */ -struct FunctionCallArgs -{ - /// Types that were used to encode `rawBytes`. Parameters - /// are usually comma separated literals. Their type is auto- - /// detected and retained in order to format them later on. - ParameterList parameters; - /// A Comment that can be attached to the expectations, - /// that is retained and can be displayed. - std::string comment; - /// ABI encoded `bytes` of parsed parameters. These `bytes` - /// passed to the function call. - bytes rawBytes() const - { - bytes raw; - for (auto const& param: parameters) - raw += param.rawBytes; - return raw; - } -}; - -/** - * Represents a function call read from an input stream. It contains the signature, the - * arguments, an optional ether value and an expected execution result. - */ -struct FunctionCall -{ - /// Signature of the function call, e.g. `f(uint256, uint256)`. - std::string signature; - /// Optional `ether` value that can be send with the call. - u256 value; - /// Object that holds all function parameters in their `bytes` - /// representations given by the contract ABI. - FunctionCallArgs arguments; - /// Object that holds all function call expectation in - /// their `bytes` representations given by the contract ABI. - /// They are checked against the actual results and their - /// `bytes` representation, as well as the transaction status. - FunctionCallExpectations expectations; - /// single / multi-line mode will be detected as follows: - /// every newline (//) in source results in a function call - /// that has its display mode set to multi-mode. Function and - /// result parameter lists are an exception: a single parameter - /// stores a format information that contains a newline definition. - enum DisplayMode { - SingleLine, - MultiLine - }; - DisplayMode displayMode = DisplayMode::SingleLine; - /// Marks this function call as the constructor. - bool isConstructor = false; -}; - /** * Class that is able to parse an additional and well-formed comment section in a Solidity * source file used by the file-based unit test environment. For now, it parses function @@ -398,22 +179,6 @@ private: /// Parses the current string literal. std::string parseString(); - /// Tries to convert \param _literal to an unpadded `bytes` - /// representation of the boolean number literal. Throws if conversion fails. - bytes convertBoolean(std::string const& _literal); - - /// Tries to convert \param _literal to an unpadded `bytes` - /// representation of the decimal number literal. Throws if conversion fails. - bytes convertNumber(std::string const& _literal); - - /// Tries to convert \param _literal to an unpadded `bytes` - /// representation of the hex literal. Throws if conversion fails. - bytes convertHexNumber(std::string const& _literal); - - /// Tries to convert \param _literal to an unpadded `bytes` - /// representation of the string literal. Throws if conversion fails. - bytes convertString(std::string const& _literal); - /// A scanner instance Scanner m_scanner; }; diff --git a/test/libsolidity/util/TestFunctionCall.cpp b/test/libsolidity/util/TestFunctionCall.cpp index 15c4d50bb..4b9e39c19 100644 --- a/test/libsolidity/util/TestFunctionCall.cpp +++ b/test/libsolidity/util/TestFunctionCall.cpp @@ -14,11 +14,13 @@ #include +#include +#include + #include #include -#include #include #include @@ -27,47 +29,6 @@ using namespace solidity; using namespace dev::solidity::test; using namespace std; -namespace -{ - -static regex s_boolType{"(bool)"}; -static regex s_uintType{"(uint\\d*)"}; -static regex s_intType{"(int\\d*)"}; -static regex s_bytesType{"(bytes\\d+)"}; -static regex s_dynBytesType{"(\\bbytes\\b)"}; -static regex s_stringType{"(string)"}; - -/// Translates Solidity's ABI types into the internal type representation of -/// soltest. -auto contractABITypes(string const& _type) -> vector -{ - vector abiTypes; - if (regex_match(_type, s_boolType)) - abiTypes.push_back(ABIType{ABIType::Boolean, ABIType::AlignRight, 32}); - else if (regex_match(_type, s_uintType)) - abiTypes.push_back(ABIType{ABIType::UnsignedDec, ABIType::AlignRight, 32}); - else if (regex_match(_type, s_intType)) - abiTypes.push_back(ABIType{ABIType::SignedDec, ABIType::AlignRight, 32}); - else if (regex_match(_type, s_bytesType)) - abiTypes.push_back(ABIType{ABIType::Hex, ABIType::AlignRight, 32}); - else if (regex_match(_type, s_dynBytesType)) - { - abiTypes.push_back(ABIType{ABIType::UnsignedDec, ABIType::AlignRight, 32}); - abiTypes.push_back(ABIType{ABIType::UnsignedDec, ABIType::AlignRight, 32}); - abiTypes.push_back(ABIType{ABIType::HexString, ABIType::AlignLeft, 32}); - } - else if (regex_match(_type, s_stringType)) - { - abiTypes.push_back(ABIType{ABIType::UnsignedDec, ABIType::AlignRight, 32}); - abiTypes.push_back(ABIType{ABIType::UnsignedDec, ABIType::AlignRight, 32}); - abiTypes.push_back(ABIType{ABIType::String, ABIType::AlignLeft, 32}); - } - else - abiTypes.push_back(ABIType{ABIType::None, ABIType::AlignRight, 0}); - return abiTypes; -}; -} - string TestFunctionCall::format( ErrorReporter& _errorReporter, string const& _linePrefix, @@ -192,21 +153,9 @@ string TestFunctionCall::formatBytesParameters( stringstream os; string functionName{_signature.substr(0, _signature.find("("))}; - auto sizeFold = [](size_t const _a, Parameter const& _b) { return _a + _b.abiType.size; }; - size_t encodingSize = std::accumulate(_params.begin(), _params.end(), size_t{0}, sizeFold); - - /// Infer type from Contract ABI. Used to generate values for + /// Create parameters from Contract ABI. Used to generate values for /// auto-correction during interactive update routine. - ParameterList abiParams; - for (auto const& function: m_contractABI) - if (function["name"] == functionName) - for (auto const& output: function["outputs"]) - { - auto types = contractABITypes(output["type"].asString()); - for (auto const& type: types) - abiParams.push_back(Parameter{bytes(), "", type, FormatInfo{}}); - } - + ParameterList abiParams = ContractABIUtils().parametersFromJson(m_contractABI, functionName); /// If parameter count does not match, take types defined by ABI, but only /// if the contract ABI is defined (needed for format tests where the actual @@ -214,6 +163,9 @@ string TestFunctionCall::formatBytesParameters( ParameterList preferredParams; if (m_contractABI && (_params.size() != abiParams.size())) { + auto sizeFold = [](size_t const _a, Parameter const& _b) { return _a + _b.abiType.size; }; + size_t encodingSize = std::accumulate(_params.begin(), _params.end(), size_t{0}, sizeFold); + _errorReporter.warning( "Encoding does not match byte range. The call returned " + to_string(_bytes.size()) + " bytes, but " + @@ -294,57 +246,23 @@ string TestFunctionCall::formatBytesRange( // be signed. If an unsigned was detected in the expectations, // but the actual result returned a signed, it would be formatted // incorrectly. - if (*_bytes.begin() & 0x80) - os << u2s(fromBigEndian(_bytes)); - else - os << fromBigEndian(_bytes); + os << BytesUtils().formatUnsigned(_bytes); break; case ABIType::SignedDec: - if (*_bytes.begin() & 0x80) - os << u2s(fromBigEndian(_bytes)); - else - os << fromBigEndian(_bytes); + os << BytesUtils().formatSigned(_bytes); break; case ABIType::Boolean: - { - u256 result = fromBigEndian(_bytes); - if (result == 0) - os << "false"; - else if (result == 1) - os << "true"; - else - os << result; + os << BytesUtils().formatBoolean(_bytes); break; - } case ABIType::Hex: - { - string hex{toHex(_bytes, HexPrefix::Add)}; - boost::algorithm::replace_all(hex, "00", ""); - os << hex; + os << BytesUtils().formatHex(_bytes); break; - } case ABIType::HexString: - os << "hex\"" << toHex(_bytes) << "\""; + os << BytesUtils().formatHexString(_bytes); break; case ABIType::String: - { - os << "\""; - bool expectZeros = false; - for (auto const& v: _bytes) - { - if (expectZeros && v != 0) - return {}; - if (v == 0) expectZeros = true; - else - { - if (!isprint(v) || v == '"') - return {}; - os << v; - } - } - os << "\""; + os << BytesUtils().formatString(_bytes); break; - } case ABIType::Failure: break; case ABIType::None: diff --git a/test/libsolidity/util/TestFunctionCall.h b/test/libsolidity/util/TestFunctionCall.h index 1d8bc9e98..f56abe93d 100644 --- a/test/libsolidity/util/TestFunctionCall.h +++ b/test/libsolidity/util/TestFunctionCall.h @@ -199,6 +199,14 @@ private: std::string const& _linePrefix = "" ) const; + /// If parameter count does not match, take types defined by ABI, but only + /// if the contract ABI is defined (needed for format tests where the actual + /// result does not matter). + ParameterList choosePreferredParameters( + ParameterList const& _parsedParamters, + ParameterList const& _abiParameters + ) const; + /// Compares raw expectations (which are converted to a byte representation before), /// and also the expected transaction status of the function call to the actual test results. bool matchesExpectation() const; diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index b9e72d27b..cafb5f3f6 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -16,6 +16,8 @@ add_executable(isoltest ../Options.cpp ../Common.cpp ../TestCase.cpp + ../libsolidity/util/BytesUtils.cpp + ../libsolidity/util/ContractABIUtils.cpp ../libsolidity/util/TestFileParser.cpp ../libsolidity/util/TestFunctionCall.cpp ../libsolidity/GasTest.cpp From d06be2c53f1b23220f6361be1e38639a72e92b80 Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Thu, 4 Jul 2019 15:23:47 +0200 Subject: [PATCH 2/2] Restructures alignment and bytes utils in isoltest. --- test/libsolidity/util/BytesUtils.cpp | 33 ++++++ test/libsolidity/util/BytesUtils.h | 16 +++ test/libsolidity/util/SoltestTypes.h | 9 ++ test/libsolidity/util/TestFileParser.cpp | 137 +++++++++-------------- test/libsolidity/util/TestFileParser.h | 6 +- test/libsolidity/util/TestFunctionCall.h | 8 -- 6 files changed, 115 insertions(+), 94 deletions(-) diff --git a/test/libsolidity/util/BytesUtils.cpp b/test/libsolidity/util/BytesUtils.cpp index 1659324de..dfaa76d06 100644 --- a/test/libsolidity/util/BytesUtils.cpp +++ b/test/libsolidity/util/BytesUtils.cpp @@ -163,3 +163,36 @@ string BytesUtils::formatString(bytes const& _bytes) const return os.str(); } + +bytes BytesUtils::alignLeft(bytes _bytes) const +{ + return std::move(_bytes) + bytes(32 - _bytes.size(), 0); +} + +bytes BytesUtils::alignRight(bytes _bytes) const +{ + return bytes(32 - _bytes.size(), 0) + std::move(_bytes); +} + +bytes BytesUtils::applyAlign( + Parameter::Alignment _alignment, + ABIType& _abiType, + bytes _bytes +) const +{ + if (_alignment != Parameter::Alignment::None) + _abiType.alignDeclared = true; + + switch (_alignment) + { + case Parameter::Alignment::Left: + _abiType.align = ABIType::AlignLeft; + return alignLeft(std::move(_bytes)); + case Parameter::Alignment::Right: + _abiType.align = ABIType::AlignRight; + return alignRight(std::move(_bytes)); + default: + _abiType.align = ABIType::AlignRight; + return alignRight(std::move(_bytes)); + } +} diff --git a/test/libsolidity/util/BytesUtils.h b/test/libsolidity/util/BytesUtils.h index 4bcf1a5b4..c090e179e 100644 --- a/test/libsolidity/util/BytesUtils.h +++ b/test/libsolidity/util/BytesUtils.h @@ -77,6 +77,22 @@ public: /// string representation of a byte array which is assumed to hold /// a string value. std::string formatString(bytes const& _bytes) const; + + /// Left-aligns and pads given _bytes and returns a new + /// bytes array. + bytes alignLeft(bytes _bytes) const; + + /// Right-aligns and pads given _bytes and returns a new + /// bytes array. + bytes alignRight(bytes _bytes) const; + + /// Applies given _alignment to _bytes and returns a new + /// bytes array. + bytes applyAlign( + Parameter::Alignment _alignment, + ABIType& _abiType, + bytes _bytes + ) const; }; } diff --git a/test/libsolidity/util/SoltestTypes.h b/test/libsolidity/util/SoltestTypes.h index 9eba08869..9d57a9246 100644 --- a/test/libsolidity/util/SoltestTypes.h +++ b/test/libsolidity/util/SoltestTypes.h @@ -135,6 +135,13 @@ struct FormatInfo */ struct Parameter { + enum Alignment + { + Left, + Right, + None, + }; + /// ABI encoded / decoded `bytes` of values. /// These `bytes` are used to pass values to function calls /// and also to store expected return vales. These are @@ -151,6 +158,8 @@ struct Parameter /// Format info attached to the parameter. It handles newlines given /// in the declaration of it. FormatInfo format; + /// Stores the parsed alignment, which can be either left(...) or right(...). + Alignment alignment = Alignment::None; }; using ParameterList = std::vector; diff --git a/test/libsolidity/util/TestFileParser.cpp b/test/libsolidity/util/TestFileParser.cpp index 05f883be5..e2c56685e 100644 --- a/test/libsolidity/util/TestFileParser.cpp +++ b/test/libsolidity/util/TestFileParser.cpp @@ -38,45 +38,6 @@ using namespace dev::solidity::test; using namespace std; using namespace soltest; -namespace -{ - enum class DeclaredAlignment - { - Left, - Right, - None, - }; - - inline bytes alignLeft(bytes _bytes) - { - return std::move(_bytes) + bytes(32 - _bytes.size(), 0); - } - - inline bytes alignRight(bytes _bytes) - { - return bytes(32 - _bytes.size(), 0) + std::move(_bytes); - } - - inline bytes applyAlign(DeclaredAlignment _alignment, ABIType& _abiType, bytes _converted) - { - if (_alignment != DeclaredAlignment::None) - _abiType.alignDeclared = true; - - switch (_alignment) - { - case DeclaredAlignment::Left: - _abiType.align = ABIType::AlignLeft; - return alignLeft(std::move(_converted)); - case DeclaredAlignment::Right: - _abiType.align = ABIType::AlignRight; - return alignRight(std::move(_converted)); - default: - _abiType.align = ABIType::AlignRight; - return alignRight(std::move(_converted)); - } - } -} - char TestFileParser::Scanner::peek() const noexcept { if (std::distance(m_char, m_line.end()) < 2) @@ -248,112 +209,124 @@ Parameter TestFileParser::parseParameter() if (accept(Token::Newline, true)) parameter.format.newline = true; - auto literal = parseABITypeLiteral(); - parameter.rawBytes = get<0>(literal); - parameter.abiType = get<1>(literal); - parameter.rawString = get<2>(literal); - - return parameter; -} - -tuple TestFileParser::parseABITypeLiteral() -{ - ABIType abiType{ABIType::None, ABIType::AlignNone, 0}; - DeclaredAlignment alignment{DeclaredAlignment::None}; - bytes result{toBigEndian(u256{0})}; - string rawString; bool isSigned = false; if (accept(Token::Left, true)) { - rawString += formatToken(Token::Left); + parameter.rawString += formatToken(Token::Left); expect(Token::LParen); - rawString += formatToken(Token::LParen); - alignment = DeclaredAlignment::Left; + parameter.rawString += formatToken(Token::LParen); + parameter.alignment = Parameter::Alignment::Left; } if (accept(Token::Right, true)) { - rawString += formatToken(Token::Right); + parameter.rawString += formatToken(Token::Right); expect(Token::LParen); - rawString += formatToken(Token::LParen); - alignment = DeclaredAlignment::Right; + parameter.rawString += formatToken(Token::LParen); + parameter.alignment = Parameter::Alignment::Right; } try { if (accept(Token::Sub, true)) { - rawString += formatToken(Token::Sub); + parameter.rawString += formatToken(Token::Sub); isSigned = true; } if (accept(Token::Boolean)) { if (isSigned) throw Error(Error::Type::ParserError, "Invalid boolean literal."); - abiType = ABIType{ABIType::Boolean, ABIType::AlignRight, 32}; + + parameter.abiType = ABIType{ABIType::Boolean, ABIType::AlignRight, 32}; string parsed = parseBoolean(); - rawString += parsed; - result = applyAlign(alignment, abiType, BytesUtils().convertBoolean(parsed)); + parameter.rawString += parsed; + parameter.rawBytes = BytesUtils().applyAlign( + parameter.alignment, + parameter.abiType, + BytesUtils().convertBoolean(parsed) + ); } else if (accept(Token::HexNumber)) { if (isSigned) throw Error(Error::Type::ParserError, "Invalid hex number literal."); - abiType = ABIType{ABIType::Hex, ABIType::AlignRight, 32}; + + parameter.abiType = ABIType{ABIType::Hex, ABIType::AlignRight, 32}; string parsed = parseHexNumber(); - rawString += parsed; - result = applyAlign(alignment, abiType, BytesUtils().convertHexNumber(parsed)); + parameter.rawString += parsed; + parameter.rawBytes = BytesUtils().applyAlign( + parameter.alignment, + parameter.abiType, + BytesUtils().convertHexNumber(parsed) + ); } else if (accept(Token::Hex, true)) { if (isSigned) throw Error(Error::Type::ParserError, "Invalid hex string literal."); - if (alignment != DeclaredAlignment::None) + if (parameter.alignment != Parameter::Alignment::None) throw Error(Error::Type::ParserError, "Hex string literals cannot be aligned or padded."); + string parsed = parseString(); - rawString += "hex\"" + parsed + "\""; - result = BytesUtils().convertHexNumber(parsed); - abiType = ABIType{ABIType::HexString, ABIType::AlignNone, result.size()}; + parameter.rawString += "hex\"" + parsed + "\""; + parameter.rawBytes = BytesUtils().convertHexNumber(parsed); + parameter.abiType = ABIType{ + ABIType::HexString, ABIType::AlignNone, parameter.rawBytes.size() + }; } else if (accept(Token::String)) { if (isSigned) throw Error(Error::Type::ParserError, "Invalid string literal."); - if (alignment != DeclaredAlignment::None) + if (parameter.alignment != Parameter::Alignment::None) throw Error(Error::Type::ParserError, "String literals cannot be aligned or padded."); - abiType = ABIType{ABIType::String, ABIType::AlignLeft, 32}; + + parameter.abiType = ABIType{ABIType::String, ABIType::AlignLeft, 32}; string parsed = parseString(); - rawString += "\"" + parsed + "\""; - result = applyAlign(DeclaredAlignment::Left, abiType, BytesUtils().convertString(parsed)); + parameter.rawString += "\"" + parsed + "\""; + parameter.rawBytes = BytesUtils().applyAlign( + Parameter::Alignment::Left, + parameter.abiType, + BytesUtils().convertString(parsed) + ); } else if (accept(Token::Number)) { auto type = isSigned ? ABIType::SignedDec : ABIType::UnsignedDec; - abiType = ABIType{type, ABIType::AlignRight, 32}; + + parameter.abiType = ABIType{type, ABIType::AlignRight, 32}; string parsed = parseDecimalNumber(); - rawString += parsed; + parameter.rawString += parsed; if (isSigned) parsed = "-" + parsed; - result = applyAlign(alignment, abiType, BytesUtils().convertNumber(parsed)); + + parameter.rawBytes = BytesUtils().applyAlign( + parameter.alignment, + parameter.abiType, + BytesUtils().convertNumber(parsed) + ); } else if (accept(Token::Failure, true)) { if (isSigned) throw Error(Error::Type::ParserError, "Invalid failure literal."); - abiType = ABIType{ABIType::Failure, ABIType::AlignRight, 0}; - result = bytes{}; + + parameter.abiType = ABIType{ABIType::Failure, ABIType::AlignRight, 0}; + parameter.rawBytes = bytes{}; } - if (alignment != DeclaredAlignment::None) + if (parameter.alignment != Parameter::Alignment::None) { expect(Token::RParen); - rawString += formatToken(Token::RParen); + parameter.rawString += formatToken(Token::RParen); } - return make_tuple(result, abiType, rawString); } catch (std::exception const&) { throw Error(Error::Type::ParserError, "Literal encoding invalid."); } + + return parameter; } string TestFileParser::parseIdentifierOrTuple() diff --git a/test/libsolidity/util/TestFileParser.h b/test/libsolidity/util/TestFileParser.h index 2eb2b793f..21915564e 100644 --- a/test/libsolidity/util/TestFileParser.h +++ b/test/libsolidity/util/TestFileParser.h @@ -146,9 +146,7 @@ private: /// appends it to the internal `bytes` buffer of the parameter. It can also /// store newlines found in the source, that are needed to /// format input and output of the interactive update. - Parameter parseParameter(); - - /// Parses and converts the current literal to its byte representation and + /// Parses and converts the current literal to its byte representation and /// preserves the chosen ABI type, as well as a raw, unformatted string representation /// of this literal. /// Based on the type information retrieved, the driver of this parser may format arguments, @@ -157,7 +155,7 @@ private: /// Returns invalid ABI type for empty literal. This is needed in order /// to detect empty expectations. Throws a ParserError if data is encoded incorrectly or /// if data type is not supported. - std::tuple parseABITypeLiteral(); + Parameter parseParameter(); /// Recursively parses an identifier or a tuple definition that contains identifiers /// and / or parentheses like `((uint, uint), (uint, (uint, uint)), uint)`. diff --git a/test/libsolidity/util/TestFunctionCall.h b/test/libsolidity/util/TestFunctionCall.h index f56abe93d..1d8bc9e98 100644 --- a/test/libsolidity/util/TestFunctionCall.h +++ b/test/libsolidity/util/TestFunctionCall.h @@ -199,14 +199,6 @@ private: std::string const& _linePrefix = "" ) const; - /// If parameter count does not match, take types defined by ABI, but only - /// if the contract ABI is defined (needed for format tests where the actual - /// result does not matter). - ParameterList choosePreferredParameters( - ParameterList const& _parsedParamters, - ParameterList const& _abiParameters - ) const; - /// Compares raw expectations (which are converted to a byte representation before), /// and also the expected transaction status of the function call to the actual test results. bool matchesExpectation() const;