diff options
Diffstat (limited to 'test/libsolidity/SolidityParser.cpp')
-rw-r--r-- | test/libsolidity/SolidityParser.cpp | 128 |
1 files changed, 103 insertions, 25 deletions
diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index 5e3c69d2..78edd4d1 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -24,8 +24,9 @@ #include <memory> #include <libsolidity/parsing/Scanner.h> #include <libsolidity/parsing/Parser.h> -#include <libsolidity/interface/Exceptions.h> +#include <libsolidity/interface/ErrorReporter.h> #include "../TestHelper.h" +#include "ErrorCheck.h" using namespace std; @@ -40,7 +41,8 @@ namespace { ASTPointer<ContractDefinition> parseText(std::string const& _source, ErrorList& _errors) { - ASTPointer<SourceUnit> sourceUnit = Parser(_errors).parse(std::make_shared<Scanner>(CharStream(_source))); + ErrorReporter errorReporter(_errors); + ASTPointer<SourceUnit> sourceUnit = Parser(errorReporter).parse(std::make_shared<Scanner>(CharStream(_source))); if (!sourceUnit) return ASTPointer<ContractDefinition>(); for (ASTPointer<ASTNode> const& node: sourceUnit->nodes()) @@ -71,6 +73,22 @@ bool successParse(std::string const& _source) return true; } +Error getError(std::string const& _source) +{ + ErrorList errors; + try + { + parseText(_source, errors); + } + catch (FatalError const& /*_exception*/) + { + // no-op + } + Error const* error = Error::containsErrorOfType(errors, Error::Type::ParserError); + BOOST_REQUIRE(error); + return *error; +} + void checkFunctionNatspec( FunctionDefinition const* _function, std::string const& _expectedDoc @@ -83,6 +101,14 @@ void checkFunctionNatspec( } +#define CHECK_PARSE_ERROR(source, substring) \ +do \ +{\ + Error err = getError((source)); \ + BOOST_CHECK(searchErrorMessage(err, (substring))); \ +}\ +while(0) + BOOST_AUTO_TEST_SUITE(SolidityParser) @@ -103,7 +129,7 @@ BOOST_AUTO_TEST_CASE(missing_variable_name_in_declaration) uint256 ; } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(empty_function) @@ -159,7 +185,7 @@ BOOST_AUTO_TEST_CASE(missing_parameter_name_in_named_args) function b() returns (uint r) { r = a({: 1, : 2, : 3}); } } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(missing_argument_in_named_args) @@ -170,7 +196,18 @@ BOOST_AUTO_TEST_CASE(missing_argument_in_named_args) function b() returns (uint r) { r = a({a: , b: , c: }); } } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected primary expression"); +} + +BOOST_AUTO_TEST_CASE(trailing_comma_in_named_args) +{ + char const* text = R"( + contract test { + function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; } + function b() returns (uint r) { r = a({a: 1, b: 2, c: 3, }); } + } + )"; + CHECK_PARSE_ERROR(text, "Unexpected trailing comma"); } BOOST_AUTO_TEST_CASE(two_exact_functions) @@ -463,7 +500,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_function_parameter) function fun(var a) {} } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected explicit type name"); } BOOST_AUTO_TEST_CASE(variable_definition_in_mapping) @@ -475,7 +512,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_mapping) } } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected elementary type name for mapping key type"); } BOOST_AUTO_TEST_CASE(variable_definition_in_function_return) @@ -487,7 +524,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_function_return) } } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected explicit type name"); } BOOST_AUTO_TEST_CASE(operator_expression) @@ -777,14 +814,14 @@ BOOST_AUTO_TEST_CASE(modifier_without_semicolon) modifier mod { if (msg.sender == 0) _ } } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected token Semicolon got"); } BOOST_AUTO_TEST_CASE(modifier_arguments) { char const* text = R"( contract c { - modifier mod(uint a) { if (msg.sender == a) _; } + modifier mod(address a) { if (msg.sender == a) _; } } )"; BOOST_CHECK(successParse(text)); @@ -861,7 +898,25 @@ BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers) contract c { uint private internal a; })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Visibility already specified"); +} + +BOOST_AUTO_TEST_CASE(multiple_payable_specifiers) +{ + char const* text = R"( + contract c { + function f() payable payable {} + })"; + CHECK_PARSE_ERROR(text, "Multiple \"payable\" specifiers."); +} + +BOOST_AUTO_TEST_CASE(multiple_constant_specifiers) +{ + char const* text = R"( + contract c { + function f() constant constant {} + })"; + CHECK_PARSE_ERROR(text, "Multiple \"constant\" specifiers."); } BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations) @@ -916,7 +971,7 @@ BOOST_AUTO_TEST_CASE(empty_enum_declaration) contract c { enum foo { } })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "enum with no members is not allowed"); } BOOST_AUTO_TEST_CASE(malformed_enum_declaration) @@ -925,7 +980,7 @@ BOOST_AUTO_TEST_CASE(malformed_enum_declaration) contract c { enum foo { WARNING,} })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected Identifier after"); } BOOST_AUTO_TEST_CASE(external_function) @@ -943,7 +998,7 @@ BOOST_AUTO_TEST_CASE(external_variable) contract c { uint external x; })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(arrays_in_storage) @@ -991,7 +1046,7 @@ BOOST_AUTO_TEST_CASE(constant_is_keyword) contract Foo { uint constant = 4; })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(var_array) @@ -1000,7 +1055,7 @@ BOOST_AUTO_TEST_CASE(var_array) contract Foo { function f() { var[] a; } })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(location_specifiers_for_params) @@ -1032,7 +1087,7 @@ BOOST_AUTO_TEST_CASE(location_specifiers_for_state) contract Foo { uint[] memory x; })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(location_specifiers_with_var) @@ -1041,7 +1096,7 @@ BOOST_AUTO_TEST_CASE(location_specifiers_with_var) contract Foo { function f() { var memory x; } })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Location specifier needs explicit type name"); } BOOST_AUTO_TEST_CASE(empty_comment) @@ -1088,7 +1143,7 @@ BOOST_AUTO_TEST_CASE(local_const_variable) return local; } })"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected token Semicolon"); } BOOST_AUTO_TEST_CASE(multi_variable_declaration) @@ -1207,7 +1262,7 @@ BOOST_AUTO_TEST_CASE(inline_array_empty_cells_check_lvalue) } } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected expression"); } BOOST_AUTO_TEST_CASE(inline_array_empty_cells_check_without_lvalue) @@ -1220,7 +1275,7 @@ BOOST_AUTO_TEST_CASE(inline_array_empty_cells_check_without_lvalue) } } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected expression"); } BOOST_AUTO_TEST_CASE(conditional_true_false_literal) @@ -1321,7 +1376,7 @@ BOOST_AUTO_TEST_CASE(no_double_radix_in_fixed_literal) fixed40x40 pi = 3.14.15; } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected token Semicolon"); } BOOST_AUTO_TEST_CASE(invalid_fixed_conversion_leading_zeroes_check) @@ -1333,7 +1388,7 @@ BOOST_AUTO_TEST_CASE(invalid_fixed_conversion_leading_zeroes_check) } } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected primary expression"); } BOOST_AUTO_TEST_CASE(payable_accessor) @@ -1343,7 +1398,7 @@ BOOST_AUTO_TEST_CASE(payable_accessor) uint payable x; } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected identifier"); } BOOST_AUTO_TEST_CASE(function_type_in_expression) @@ -1376,7 +1431,7 @@ BOOST_AUTO_TEST_CASE(function_type_as_storage_variable_with_modifiers) function (uint, uint) modifier1() returns (uint) f1; } )"; - BOOST_CHECK(!successParse(text)); + CHECK_PARSE_ERROR(text, "Expected token LBrace"); } BOOST_AUTO_TEST_CASE(function_type_as_storage_variable_with_assignment) @@ -1454,6 +1509,29 @@ BOOST_AUTO_TEST_CASE(function_type_state_variable) BOOST_CHECK(successParse(text)); } +BOOST_AUTO_TEST_CASE(scientific_notation) +{ + char const* text = R"( + contract test { + uint256 a = 2e10; + uint256 b = 2E10; + uint256 c = 200e-2; + uint256 d = 2E10 wei; + uint256 e = 2.5e10; + } + )"; + BOOST_CHECK(successParse(text)); +} + +BOOST_AUTO_TEST_CASE(interface) +{ + char const* text = R"( + interface Interface { + function f(); + } + )"; + BOOST_CHECK(successParse(text)); +} BOOST_AUTO_TEST_SUITE_END() |