From fb41b96bb89d2e250759159f992b460442fa0b06 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 15 Jan 2015 20:04:06 +0100 Subject: Import inherited members into the contract's scope. --- SolidityNameAndTypeResolution.cpp | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index e2b4f160..f4a1abbd 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -357,7 +357,6 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature_type_aliases) } } - BOOST_AUTO_TEST_CASE(hash_collision_in_interface) { char const* text = "contract test {\n" @@ -369,6 +368,40 @@ BOOST_AUTO_TEST_CASE(hash_collision_in_interface) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(inheritance_basic) +{ + char const* text = R"( + contract base { uint baseMember; struct BaseType { uint element; } } + contract derived is base { + BaseType data; + function f() { baseMember = 7; } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(inheritance_diamond_basic) +{ + char const* text = R"( + contract root { function rootFunction() {} } + contract inter1 is root { function f() {} } + contract inter2 is root { function f() {} } + contract derived is inter1, inter2, root { + function g() { f(); rootFunction(); } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(cyclic_inheritance) +{ + char const* text = R"( + contract A is B { } + contract B is A { } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } -- cgit v1.2.3 From 580d712a671c8ac576decba34c0a4f2282585a15 Mon Sep 17 00:00:00 2001 From: Christian Date: Fri, 16 Jan 2015 17:50:10 +0100 Subject: Check overrides and provide inherited public interface. --- SolidityNameAndTypeResolution.cpp | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index f4a1abbd..8cc45ce6 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -402,6 +402,55 @@ BOOST_AUTO_TEST_CASE(cyclic_inheritance) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(illegal_override_direct) +{ + char const* text = R"( + contract B { function f() {} } + contract C is B { function f(uint i) {} } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(illegal_override_indirect) +{ + char const* text = R"( + contract A { function f(uint a) {} } + contract B { function f() {} } + contract C is A, B { } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(complex_inheritance) +{ + char const* text = R"( + contract A { function f() { uint8 x = C(0).g(); } } + contract B { function f() {} function g() returns (uint8 r) {} } + contract C is A, B { } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(constructor_visibility) +{ + // The constructor of a base class should not be visible in the derived class + char const* text = R"( + contract A { function A() { } } + contract B is A { function f() { A x = A(0); } } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(overriding_constructor) +{ + // It is fine to "override" constructor of a base class since it is invisible + char const* text = R"( + contract A { function A() { } } + contract B is A { function A() returns (uint8 r) {} } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + BOOST_AUTO_TEST_SUITE_END() } -- cgit v1.2.3 From 961cb5b90c70534df3704c2a905fa0b42f35bfbd Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 19 Jan 2015 23:08:48 +0100 Subject: Call constructors of base classes. --- SolidityNameAndTypeResolution.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 8cc45ce6..c0ebb0ed 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -451,6 +451,24 @@ BOOST_AUTO_TEST_CASE(overriding_constructor) BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } +BOOST_AUTO_TEST_CASE(missing_base_constructor_arguments) +{ + char const* text = R"( + contract A { function A(uint a) { } } + contract B is A { } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(base_constructor_arguments_override) +{ + char const* text = R"( + contract A { function A(uint a) { } } + contract B is A { } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } -- cgit v1.2.3 From 609268ee624a2ea6af4ed11a9830272faf6082bb Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 19 Jan 2015 23:34:49 +0100 Subject: Implicit conversion from derived to base. --- SolidityNameAndTypeResolution.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index c0ebb0ed..6c8fd1b1 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -469,6 +469,27 @@ BOOST_AUTO_TEST_CASE(base_constructor_arguments_override) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(implicit_derived_to_base_conversion) +{ + char const* text = R"( + contract A { } + contract B is A { + function f() { A a = B(1); } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} +BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion) +{ + char const* text = R"( + contract A { } + contract B is A { + function f() { B b = A(1); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } -- cgit v1.2.3 From 682a45290c5d40651af096a84fba6ffc570e7e59 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 26 Jan 2015 10:20:46 +0100 Subject: Reverse order of inheritance in base list. --- SolidityNameAndTypeResolution.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 6c8fd1b1..079da0a1 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -386,7 +386,7 @@ BOOST_AUTO_TEST_CASE(inheritance_diamond_basic) contract root { function rootFunction() {} } contract inter1 is root { function f() {} } contract inter2 is root { function f() {} } - contract derived is inter1, inter2, root { + contract derived is root, inter2, inter1 { function g() { f(); rootFunction(); } } )"; -- cgit v1.2.3 From c86a46b84d13cd0c12c6a2ea1bc2b096b9d1a539 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 22 Jan 2015 01:02:38 +0100 Subject: Type resolution for function modifiers. --- SolidityNameAndTypeResolution.cpp | 83 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 6c8fd1b1..c195539f 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -479,6 +479,7 @@ BOOST_AUTO_TEST_CASE(implicit_derived_to_base_conversion) )"; BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } + BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion) { char const* text = R"( @@ -490,6 +491,88 @@ BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(function_modifier_invocation) +{ + char const* text = R"( + contract B { + function f() mod1(2, true) mod2("0123456") { } + modifier mod1(uint a, bool b) { if (b) _ } + modifier mod2(string7 a) { while (a == "1234567") _ } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(invalid_function_modifier_type) +{ + char const* text = R"( + contract B { + function f() mod1(true) { } + modifier mod1(uint a) { if (a > 0) _ } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(function_modifier_invocation_parameters) +{ + char const* text = R"( + contract B { + function f(uint8 a) mod1(a, true) mod2(r) returns (string7 r) { } + modifier mod1(uint a, bool b) { if (b) _ } + modifier mod2(string7 a) { while (a == "1234567") _ } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables) +{ + char const* text = R"( + contract B { + function f() mod(x) { uint x = 7; } + modifier mod(uint a) { if (a > 0) _ } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(legal_modifier_override) +{ + char const* text = R"( + contract A { modifier mod(uint a) {} } + contract B is A { modifier mod(uint a) {} } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(illegal_modifier_override) +{ + char const* text = R"( + contract A { modifier mod(uint a) {} } + contract B is A { modifier mod(uint8 a) {} } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(modifier_overrides_function) +{ + char const* text = R"( + contract A { modifier mod(uint a) {} } + contract B is A { function mod(uint a) {} } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(function_overrides_modifier) +{ + char const* text = R"( + contract A { function mod(uint a) {} } + contract B is A { modifier mod(uint a) {} } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } -- cgit v1.2.3 From 67073948af86ed22c8316aec70b031203b60c7da Mon Sep 17 00:00:00 2001 From: Christian Date: Fri, 23 Jan 2015 02:35:27 +0100 Subject: Compilation of function modifiers. --- SolidityNameAndTypeResolution.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index c195539f..69559b4a 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -573,6 +573,17 @@ BOOST_AUTO_TEST_CASE(function_overrides_modifier) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(modifier_returns_value) +{ + char const* text = R"( + contract A { + function f(uint a) mod(2) returns (uint r) {} + modifier mod(uint a) { return 7; } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } -- cgit v1.2.3 From 9e8fa8b08a1a322efbd099b17af603dca5401fba Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 22 Jan 2015 17:43:16 +0100 Subject: Tests for variable state accessors are in progress --- SolidityNameAndTypeResolution.cpp | 62 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 3720b3cd..7728414d 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -53,6 +54,48 @@ ASTPointer parseTextAndResolveNames(std::string const& _source) return sourceUnit; } + +ASTPointer parseTextAndResolveNamesWithChecks(std::string const& _source) +{ + Parser parser; + ASTPointer sourceUnit; + try + { + sourceUnit = parser.parse(std::make_shared(CharStream(_source))); + NameAndTypeResolver resolver({}); + resolver.registerDeclarations(*sourceUnit); + for (ASTPointer const& node: sourceUnit->getNodes()) + if (ContractDefinition* contract = dynamic_cast(node.get())) + resolver.resolveNamesAndTypes(*contract); + for (ASTPointer const& node: sourceUnit->getNodes()) + if (ContractDefinition* contract = dynamic_cast(node.get())) + resolver.checkTypeRequirements(*contract); + } + catch(boost::exception const& _e) + { + auto msg = std::string("Parsing text and resolving nanes failed with: \n") + boost::diagnostic_information(_e); + BOOST_FAIL(msg); + } + return sourceUnit; +} + +static ContractDefinition const* retrieveContract(ASTPointer _source, unsigned index) +{ + ContractDefinition* contract; + unsigned counter = 0; + for (ASTPointer const& node: _source->getNodes()) + if ((contract = dynamic_cast(node.get())) && counter == index) + return contract; + + return NULL; +} + +static FunctionDefinition const* retrieveFunctionBySignature(ContractDefinition const* _contract, + std::string const& _signature) +{ + FixedHash<4> hash(dev::sha3(_signature)); + return _contract->getInterfaceFunctions()[hash]; +} } BOOST_AUTO_TEST_SUITE(SolidityNameAndTypeResolution) @@ -63,7 +106,7 @@ BOOST_AUTO_TEST_CASE(smoke_test) " uint256 stateVariable1;\n" " function fun(uint256 arg1) { var x; uint256 y; }" "}\n"; - BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); + BOOST_CHECK_NO_THROW(parseTextAndResolveNamesWithChecks(text)); } BOOST_AUTO_TEST_CASE(double_stateVariable_declaration) @@ -584,6 +627,23 @@ BOOST_AUTO_TEST_CASE(modifier_returns_value) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(state_variable_accessors) +{ + char const* text = "contract base {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "uint256 foo;\n" + "}\n"; + + ASTPointer source; + ContractDefinition const* contract; + FunctionDefinition const* function; + BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text)); + BOOST_CHECK((contract = retrieveContract(source, 0)) != nullptr); + BOOST_CHECK((function = retrieveFunctionBySignature(contract, "foo()")) != nullptr); +} + BOOST_AUTO_TEST_SUITE_END() } -- cgit v1.2.3 From 1aa77295e563472724c886df6c92c6646b2e4a45 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 23 Jan 2015 16:37:06 +0100 Subject: State variable accessors code is now more organized - FunctionDescription is the abstraction of what should describe a function. It can either be a VariableDeclaration of a FunctionDefinition. - ParamDescription is what FunctionDescription uses to describe its parameters for outside use purposes with a pair of (name, type) strings - Modified code around Solidity and especially interface handler to adapt to this change --- SolidityNameAndTypeResolution.cpp | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 7728414d..dbb95cf7 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -30,6 +30,8 @@ #include #include +using namespace std; + namespace dev { namespace solidity @@ -39,6 +41,7 @@ namespace test namespace { + ASTPointer parseTextAndResolveNames(std::string const& _source) { Parser parser; @@ -90,8 +93,8 @@ static ContractDefinition const* retrieveContract(ASTPointer _source return NULL; } -static FunctionDefinition const* retrieveFunctionBySignature(ContractDefinition const* _contract, - std::string const& _signature) +static FunctionDescription const& retrieveFunctionBySignature(ContractDefinition const* _contract, + std::string const& _signature) { FixedHash<4> hash(dev::sha3(_signature)); return _contract->getInterfaceFunctions()[hash]; @@ -629,19 +632,40 @@ BOOST_AUTO_TEST_CASE(modifier_returns_value) BOOST_AUTO_TEST_CASE(state_variable_accessors) { - char const* text = "contract base {\n" + char const* text = "contract test {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "uint256 foo;\n" + "}\n"; + + ASTPointer source; + ContractDefinition const* contract; + BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text)); + BOOST_CHECK((contract = retrieveContract(source, 0)) != nullptr); + FunctionDescription function = retrieveFunctionBySignature(contract, "foo()"); + BOOST_CHECK_MESSAGE(function.getDeclaration() != nullptr, "Could not find the accessor function"); + // vector const expected({ParamDescription("", "uint256")}); + // BOOST_CHECK_EQUAL_COLLECTIONS(function.getReturnParameters().begin(), function.getReturnParameters().end(), + // expected.begin(), expected.end()); +} + +BOOST_AUTO_TEST_CASE(private_state_variable) +{ + char const* text = "contract test {\n" " function fun() {\n" " uint64(2);\n" " }\n" + "private:\n" "uint256 foo;\n" "}\n"; ASTPointer source; ContractDefinition const* contract; - FunctionDefinition const* function; BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text)); BOOST_CHECK((contract = retrieveContract(source, 0)) != nullptr); - BOOST_CHECK((function = retrieveFunctionBySignature(contract, "foo()")) != nullptr); + FunctionDescription function = retrieveFunctionBySignature(contract, "foo()"); + BOOST_CHECK_MESSAGE(function.getDeclaration() == nullptr, "Accessor function of a private variable should not exist"); } BOOST_AUTO_TEST_SUITE_END() -- cgit v1.2.3 From cc906541f61ce6d90797338848fe2870da42a490 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 26 Jan 2015 09:48:29 +0100 Subject: Various small fixes for Sol Automatic Accessors --- SolidityNameAndTypeResolution.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index dbb95cf7..3b711bfe 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -645,9 +645,9 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) BOOST_CHECK((contract = retrieveContract(source, 0)) != nullptr); FunctionDescription function = retrieveFunctionBySignature(contract, "foo()"); BOOST_CHECK_MESSAGE(function.getDeclaration() != nullptr, "Could not find the accessor function"); - // vector const expected({ParamDescription("", "uint256")}); - // BOOST_CHECK_EQUAL_COLLECTIONS(function.getReturnParameters().begin(), function.getReturnParameters().end(), - // expected.begin(), expected.end()); + auto returnParams = function.getReturnParameters(); + BOOST_CHECK_EQUAL(returnParams.at(0).getType(), "uint256"); + BOOST_CHECK(function.isConstant()); } BOOST_AUTO_TEST_CASE(private_state_variable) -- cgit v1.2.3 From 18eeee536d29e4cf63b106853fc68673729585d3 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 28 Jan 2015 16:48:27 +0100 Subject: Function name clashing with Statevariable accessor test --- SolidityNameAndTypeResolution.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 3b711bfe..bc0edb50 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -650,6 +650,18 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) BOOST_CHECK(function.isConstant()); } +BOOST_AUTO_TEST_CASE(function_clash_with_state_variable_accessor) +{ + char const* text = "contract test {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "uint256 foo;\n" + " function foo() {}\n" + "}\n"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError); +} + BOOST_AUTO_TEST_CASE(private_state_variable) { char const* text = "contract test {\n" -- cgit v1.2.3 From 4e67aa413e16a00c5056eb388bcf3bb011a7be57 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 28 Jan 2015 18:06:45 +0100 Subject: Various fixes pertaining to State Variable accessors --- SolidityNameAndTypeResolution.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index bc0edb50..979836ec 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -76,7 +76,7 @@ ASTPointer parseTextAndResolveNamesWithChecks(std::string const& _so } catch(boost::exception const& _e) { - auto msg = std::string("Parsing text and resolving nanes failed with: \n") + boost::diagnostic_information(_e); + auto msg = std::string("Parsing text and resolving names failed with: \n") + boost::diagnostic_information(_e); BOOST_FAIL(msg); } return sourceUnit; @@ -642,7 +642,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) ASTPointer source; ContractDefinition const* contract; BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text)); - BOOST_CHECK((contract = retrieveContract(source, 0)) != nullptr); + BOOST_REQUIRE((contract = retrieveContract(source, 0)) != nullptr); FunctionDescription function = retrieveFunctionBySignature(contract, "foo()"); BOOST_CHECK_MESSAGE(function.getDeclaration() != nullptr, "Could not find the accessor function"); auto returnParams = function.getReturnParameters(); -- cgit v1.2.3 From bdb446267332d924eb347eb138bc5f68a460b43f Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 29 Jan 2015 10:44:29 +0100 Subject: No longer exposing retrieveValueFromStorage() as a public function - plus small fix in EndToEndTests --- SolidityNameAndTypeResolution.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 979836ec..5ae854bc 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -644,7 +644,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text)); BOOST_REQUIRE((contract = retrieveContract(source, 0)) != nullptr); FunctionDescription function = retrieveFunctionBySignature(contract, "foo()"); - BOOST_CHECK_MESSAGE(function.getDeclaration() != nullptr, "Could not find the accessor function"); + BOOST_REQUIRE(function.getDeclaration() != nullptr); auto returnParams = function.getReturnParameters(); BOOST_CHECK_EQUAL(returnParams.at(0).getType(), "uint256"); BOOST_CHECK(function.isConstant()); -- cgit v1.2.3 From e77fc5c7e0df59e86df848f7ec88a419fdd66183 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 29 Jan 2015 16:39:30 +0100 Subject: Contract Interface Functions now return FunctionType - Enchanced Function Type by declaration so that it can provide all the required information at each place interface functions are consumed - Changed all places where interface functions was used. - Simplified Mix's FunctionDefinition code --- SolidityNameAndTypeResolution.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 5ae854bc..26406e1f 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -93,8 +93,8 @@ static ContractDefinition const* retrieveContract(ASTPointer _source return NULL; } -static FunctionDescription const& retrieveFunctionBySignature(ContractDefinition const* _contract, - std::string const& _signature) +static std::shared_ptr const& retrieveFunctionBySignature(ContractDefinition const* _contract, + std::string const& _signature) { FixedHash<4> hash(dev::sha3(_signature)); return _contract->getInterfaceFunctions()[hash]; @@ -643,11 +643,11 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) ContractDefinition const* contract; BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text)); BOOST_REQUIRE((contract = retrieveContract(source, 0)) != nullptr); - FunctionDescription function = retrieveFunctionBySignature(contract, "foo()"); - BOOST_REQUIRE(function.getDeclaration() != nullptr); - auto returnParams = function.getReturnParameters(); - BOOST_CHECK_EQUAL(returnParams.at(0).getType(), "uint256"); - BOOST_CHECK(function.isConstant()); + std::shared_ptr function = retrieveFunctionBySignature(contract, "foo()"); + BOOST_CHECK_MESSAGE(function->getDeclaration() != nullptr, "Could not find the accessor function"); + auto returnParams = function->getReturnParameterTypeNames(); + BOOST_CHECK_EQUAL(returnParams.at(0), "uint256"); + BOOST_CHECK(function->isConstant()); } BOOST_AUTO_TEST_CASE(function_clash_with_state_variable_accessor) @@ -676,8 +676,8 @@ BOOST_AUTO_TEST_CASE(private_state_variable) ContractDefinition const* contract; BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text)); BOOST_CHECK((contract = retrieveContract(source, 0)) != nullptr); - FunctionDescription function = retrieveFunctionBySignature(contract, "foo()"); - BOOST_CHECK_MESSAGE(function.getDeclaration() == nullptr, "Accessor function of a private variable should not exist"); + FunctionTypePointer function = retrieveFunctionBySignature(contract, "foo()"); + BOOST_CHECK_MESSAGE(function == nullptr, "Accessor function of a private variable should not exist"); } BOOST_AUTO_TEST_SUITE_END() -- cgit v1.2.3 From 866bd01bef58a77631d96cdae37cb2a9e2d86c39 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 29 Jan 2015 16:48:39 +0100 Subject: Removing Function and Param Description - Removing FunctionDescription and ParamDescription. All the data should now be in the FunctionType - Plus using the FunctionTypePointer alias in a few places --- SolidityNameAndTypeResolution.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 26406e1f..e330d772 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -93,8 +93,8 @@ static ContractDefinition const* retrieveContract(ASTPointer _source return NULL; } -static std::shared_ptr const& retrieveFunctionBySignature(ContractDefinition const* _contract, - std::string const& _signature) +static FunctionTypePointer const& retrieveFunctionBySignature(ContractDefinition const* _contract, + std::string const& _signature) { FixedHash<4> hash(dev::sha3(_signature)); return _contract->getInterfaceFunctions()[hash]; @@ -643,7 +643,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) ContractDefinition const* contract; BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text)); BOOST_REQUIRE((contract = retrieveContract(source, 0)) != nullptr); - std::shared_ptr function = retrieveFunctionBySignature(contract, "foo()"); + FunctionTypePointer function = retrieveFunctionBySignature(contract, "foo()"); BOOST_CHECK_MESSAGE(function->getDeclaration() != nullptr, "Could not find the accessor function"); auto returnParams = function->getReturnParameterTypeNames(); BOOST_CHECK_EQUAL(returnParams.at(0), "uint256"); -- cgit v1.2.3 From 5da76a3bbdb9c55d7c079b82d6bebfedcd7073b6 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 29 Jan 2015 18:44:14 +0100 Subject: FunctionType now returns const ref for Declaration --- SolidityNameAndTypeResolution.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index e330d772..07f2d638 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -644,7 +644,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text)); BOOST_REQUIRE((contract = retrieveContract(source, 0)) != nullptr); FunctionTypePointer function = retrieveFunctionBySignature(contract, "foo()"); - BOOST_CHECK_MESSAGE(function->getDeclaration() != nullptr, "Could not find the accessor function"); + BOOST_REQUIRE(function->hasDeclaration()); auto returnParams = function->getReturnParameterTypeNames(); BOOST_CHECK_EQUAL(returnParams.at(0), "uint256"); BOOST_CHECK(function->isConstant()); -- cgit v1.2.3 From a86a3a245219cc3d9c4e5fc146afd61f3f3e7b97 Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 29 Jan 2015 14:35:28 +0100 Subject: Parsing of events. --- SolidityNameAndTypeResolution.cpp | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 07f2d638..88f76124 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -680,6 +680,49 @@ BOOST_AUTO_TEST_CASE(private_state_variable) BOOST_CHECK_MESSAGE(function == nullptr, "Accessor function of a private variable should not exist"); } +BOOST_AUTO_TEST_CASE(event) +{ + char const* text = R"( + contract c { + event e(uint indexed a, string3 indexed s, bool indexed b); + function f() { e(2, "abc", true); } + })"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(event_too_many_indexed) +{ + char const* text = R"( + contract c { + event e(uint indexed a, string3 indexed b, bool indexed c, uint indexed d); + function f() { e(2, "abc", true); } + })"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(event_call) +{ + char const* text = R"( + contract c { + event e(uint a, string3 indexed s, bool indexed b); + function f() { e(2, "abc", true); } + })"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(event_inheritance) +{ + char const* text = R"( + contract base { + event e(uint a, string3 indexed s, bool indexed b); + } + contract c is base { + function f() { e(2, "abc", true); } + })"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + + BOOST_AUTO_TEST_SUITE_END() } -- cgit v1.2.3 From a55a99a2b0ce860134a4e30b2f27a20489f37f0a Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 29 Jan 2015 22:50:20 +0100 Subject: Fallback functions. --- SolidityNameAndTypeResolution.cpp | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 07f2d638..d081916c 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -680,6 +680,54 @@ BOOST_AUTO_TEST_CASE(private_state_variable) BOOST_CHECK_MESSAGE(function == nullptr, "Accessor function of a private variable should not exist"); } +BOOST_AUTO_TEST_CASE(fallback_function) +{ + char const* text = R"( + contract C { + uint x; + function() { x = 2; } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(fallback_function_with_arguments) +{ + char const* text = R"( + contract C { + uint x; + function(uint a) { x = 2; } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(fallback_function_twice) +{ + char const* text = R"( + contract C { + uint x; + function() { x = 2; } + function() { x = 3; } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), DeclarationError); +} + +BOOST_AUTO_TEST_CASE(fallback_function_inheritance) +{ + char const* text = R"( + contract A { + uint x; + function() { x = 1; } + } + contract C is A { + function() { x = 2; } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + BOOST_AUTO_TEST_SUITE_END() } -- cgit v1.2.3 From bf5f476a834222764c305c04940a723ec590ddd1 Mon Sep 17 00:00:00 2001 From: Christian Date: Sat, 31 Jan 2015 16:50:33 +0100 Subject: Fix scoping of event arguments. --- SolidityNameAndTypeResolution.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 13d3a5d2..b9a7140f 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -770,6 +770,15 @@ BOOST_AUTO_TEST_CASE(event_inheritance) BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } +BOOST_AUTO_TEST_CASE(multiple_events_argument_clash) +{ + char const* text = R"( + contract c { + event e1(uint a, uint e1, uint e2); + event e2(uint a, uint e1, uint e2); + })"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} BOOST_AUTO_TEST_SUITE_END() -- cgit v1.2.3 From c742c09ae6d0dad39f5cbbc33e54aa7d182c85f5 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 30 Jan 2015 16:06:56 +0100 Subject: Adding mapping treatment to FunctionType Plus a TypeResolution test for it --- SolidityNameAndTypeResolution.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index b9a7140f..df0e07e1 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -637,6 +637,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) " uint64(2);\n" " }\n" "uint256 foo;\n" + "mapping(uint=>string4) map;\n" "}\n"; ASTPointer source; @@ -644,10 +645,17 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text)); BOOST_REQUIRE((contract = retrieveContract(source, 0)) != nullptr); FunctionTypePointer function = retrieveFunctionBySignature(contract, "foo()"); - BOOST_REQUIRE(function->hasDeclaration()); + BOOST_REQUIRE(function && function->hasDeclaration()); auto returnParams = function->getReturnParameterTypeNames(); BOOST_CHECK_EQUAL(returnParams.at(0), "uint256"); BOOST_CHECK(function->isConstant()); + function = retrieveFunctionBySignature(contract, "map(uint256)"); + BOOST_REQUIRE(function && function->hasDeclaration()); + auto Params = function->getParameterTypeNames(); + BOOST_CHECK_EQUAL(returnParams.at(0), "uint256"); + returnParams = function->getReturnParameterTypeNames(); + BOOST_CHECK_EQUAL(returnParams.at(0), "string4"); + BOOST_CHECK(function->isConstant()); } BOOST_AUTO_TEST_CASE(function_clash_with_state_variable_accessor) -- cgit v1.2.3 From a38b8890bda78559cdf43a657c987eaf2153d87a Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 2 Feb 2015 17:24:09 +0100 Subject: Visibility specifiers. --- SolidityNameAndTypeResolution.cpp | 77 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 4 deletions(-) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index b9a7140f..4e01d02d 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -467,6 +467,24 @@ BOOST_AUTO_TEST_CASE(illegal_override_indirect) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(illegal_override_visibility) +{ + char const* text = R"( + contract B { function f() protected {} } + contract C is B { function f() public {} } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(illegal_override_constness) +{ + char const* text = R"( + contract B { function f() constant {} } + contract C is B { function f() {} } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_CASE(complex_inheritance) { char const* text = R"( @@ -636,7 +654,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) " function fun() {\n" " uint64(2);\n" " }\n" - "uint256 foo;\n" + "uint256 public foo;\n" "}\n"; ASTPointer source; @@ -668,16 +686,19 @@ BOOST_AUTO_TEST_CASE(private_state_variable) " function fun() {\n" " uint64(2);\n" " }\n" - "private:\n" - "uint256 foo;\n" + "uint256 private foo;\n" + "uint256 protected bar;\n" "}\n"; ASTPointer source; ContractDefinition const* contract; BOOST_CHECK_NO_THROW(source = parseTextAndResolveNamesWithChecks(text)); BOOST_CHECK((contract = retrieveContract(source, 0)) != nullptr); - FunctionTypePointer function = retrieveFunctionBySignature(contract, "foo()"); + FunctionTypePointer function; + function = retrieveFunctionBySignature(contract, "foo()"); BOOST_CHECK_MESSAGE(function == nullptr, "Accessor function of a private variable should not exist"); + function = retrieveFunctionBySignature(contract, "bar()"); + BOOST_CHECK_MESSAGE(function == nullptr, "Accessor function of a protected variable should not exist"); } BOOST_AUTO_TEST_CASE(fallback_function) @@ -780,6 +801,54 @@ BOOST_AUTO_TEST_CASE(multiple_events_argument_clash) BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } +BOOST_AUTO_TEST_CASE(access_to_default_function_visibility) +{ + char const* text = R"( + contract c { + function f() {} + } + contract d { + function g() { c(0).f(); } + })"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(access_to_protected_function) +{ + char const* text = R"( + contract c { + function f() protected {} + } + contract d { + function g() { c(0).f(); } + })"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(access_to_default_state_variable_visibility) +{ + char const* text = R"( + contract c { + uint a; + } + contract d { + function g() { c(0).a(); } + })"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(access_to_protected_state_variable) +{ + char const* text = R"( + contract c { + uint public a; + } + contract d { + function g() { c(0).a(); } + })"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + BOOST_AUTO_TEST_SUITE_END() } -- cgit v1.2.3 From 3b0ca66cd2c211f6678f26f0f97fb4552691f043 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 2 Feb 2015 17:52:50 +0100 Subject: Accessors for multiple mappings implemented --- SolidityNameAndTypeResolution.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index df0e07e1..2fe3288a 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -638,6 +638,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) " }\n" "uint256 foo;\n" "mapping(uint=>string4) map;\n" + "mapping(uint=>mapping(uint=>string4)) multiple_map;\n" "}\n"; ASTPointer source; @@ -649,10 +650,20 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) auto returnParams = function->getReturnParameterTypeNames(); BOOST_CHECK_EQUAL(returnParams.at(0), "uint256"); BOOST_CHECK(function->isConstant()); + function = retrieveFunctionBySignature(contract, "map(uint256)"); BOOST_REQUIRE(function && function->hasDeclaration()); - auto Params = function->getParameterTypeNames(); - BOOST_CHECK_EQUAL(returnParams.at(0), "uint256"); + auto params = function->getParameterTypeNames(); + BOOST_CHECK_EQUAL(params.at(0), "uint256"); + returnParams = function->getReturnParameterTypeNames(); + BOOST_CHECK_EQUAL(returnParams.at(0), "string4"); + BOOST_CHECK(function->isConstant()); + + function = retrieveFunctionBySignature(contract, "multiple_map(uint256,uint256)"); + BOOST_REQUIRE(function && function->hasDeclaration()); + params = function->getParameterTypeNames(); + BOOST_CHECK_EQUAL(params.at(0), "uint256"); + BOOST_CHECK_EQUAL(params.at(1), "uint256"); returnParams = function->getReturnParameterTypeNames(); BOOST_CHECK_EQUAL(returnParams.at(0), "string4"); BOOST_CHECK(function->isConstant()); -- cgit v1.2.3 From 7eece799f2aefa521d0cee7e7773e8c4235a0b1c Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Thu, 5 Feb 2015 00:58:20 +0800 Subject: add several type error test cases --- SolidityNameAndTypeResolution.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'SolidityNameAndTypeResolution.cpp') diff --git a/SolidityNameAndTypeResolution.cpp b/SolidityNameAndTypeResolution.cpp index 1a087592..ae6c374b 100644 --- a/SolidityNameAndTypeResolution.cpp +++ b/SolidityNameAndTypeResolution.cpp @@ -868,6 +868,42 @@ BOOST_AUTO_TEST_CASE(access_to_protected_state_variable) BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } +BOOST_AUTO_TEST_CASE(error_count_in_named_args) +{ + char const* sourceCode = "contract test {\n" + " function a(uint a, uint b) returns (uint r) { r = a + b; }\n" + " function b() returns (uint r) { r = a({a: 1}); }\n" + "}\n"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(empty_in_named_args) +{ + char const* sourceCode = "contract test {\n" + " function a(uint a, uint b) returns (uint r) { r = a + b; }\n" + " function b() returns (uint r) { r = a({}); }\n" + "}\n"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(duplicate_parameter_names_in_named_args) +{ + char const* sourceCode = "contract test {\n" + " function a(uint a, uint b) returns (uint r) { r = a + b; }\n" + " function b() returns (uint r) { r = a({a: 1, a: 2}); }\n" + "}\n"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(invalid_parameter_names_in_named_args) +{ + char const* sourceCode = "contract test {\n" + " function a(uint a, uint b) returns (uint r) { r = a + b; }\n" + " function b() returns (uint r) { r = a({a: 1, c: 2}); }\n" + "}\n"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } -- cgit v1.2.3