diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 9f7602d17668..72370f88382c 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -12835,6 +12835,106 @@ BOOST_AUTO_TEST_CASE(write_storage_external) ABI_CHECK(callContractFunction("h()"), encodeArgs(12)); } +BOOST_AUTO_TEST_CASE(modifier_area_simple) +{ + char const* sourceCode = R"( + contract C { + modifier A(uint x) { require(x == 0); _; } + + apply A(0) { + function f() public returns (uint) { return 1; } + } + apply A(1) { + function g() public returns (uint) { return 2; } + } + } + )"; + compileAndRun(sourceCode); + ABI_CHECK(callContractFunction("f()"), encodeArgs(1)); + ABI_CHECK(callContractFunction("g()"), encodeArgs()); +} + +BOOST_AUTO_TEST_CASE(modifier_area_nested) +{ + char const* sourceCode = R"( + contract C { + modifier A(uint x) { require(x == 0); _; } + + apply A(0) { + function f() public returns (uint) { return 1; } + apply A(1) { + function g() public returns (uint) { return 2; } + } + } + } + )"; + compileAndRun(sourceCode); + ABI_CHECK(callContractFunction("f()"), encodeArgs(1)); + ABI_CHECK(callContractFunction("g()"), encodeArgs()); +} + +BOOST_AUTO_TEST_CASE(modifier_area_nested_inverted) +{ + char const* sourceCode = R"( + contract C { + modifier A(uint x) { require(x == 0); _; } + + apply A(1) { + function f() public returns (uint) { return 1; } + apply A(0) { + function g() public returns (uint) { return 2; } + } + } + } + )"; + compileAndRun(sourceCode); + ABI_CHECK(callContractFunction("f()"), encodeArgs()); + ABI_CHECK(callContractFunction("g()"), encodeArgs()); +} + +BOOST_AUTO_TEST_CASE(modifier_area_extra_modifiers) +{ + char const* sourceCode = R"( + contract C { + modifier A(uint x) { require(x == 0); _;} + modifier B(uint x, uint y) { require(x == y); _;} + + apply A(0) B(1,1) { + function f() public B(2,2) returns (uint) { return 1; } + } + apply A(0) B(1,1) { + function g() public B(1,2) returns (uint) { return 2; } + } + apply A(0) B(1,2) { + function h() public B(2,2) returns (uint) { return 3; } + } + apply A(1) B(1,1) { + function i() public B(2,2) returns (uint) { return 4; } + } + } + )"; + compileAndRun(sourceCode); + ABI_CHECK(callContractFunction("f()"), encodeArgs(1)); + ABI_CHECK(callContractFunction("g()"), encodeArgs()); + ABI_CHECK(callContractFunction("h()"), encodeArgs()); + ABI_CHECK(callContractFunction("i()"), encodeArgs()); +} + +BOOST_AUTO_TEST_CASE(modifier_area_mutability) +{ + char const* sourceCode = R"( + contract C { + apply payable { + function f() returns (uint256) { + return msg.value; + } + } + } + )"; + compileAndRun(sourceCode); + ABI_CHECK(callContractFunctionWithValue("f()", 1337), encodeArgs(1337)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index 5432e9b51e01..74ddcde3c5df 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -492,7 +492,6 @@ BOOST_AUTO_TEST_CASE(keyword_is_reserved) "abstract", "after", "alias", - "apply", "auto", "case", "catch", diff --git a/test/libsolidity/syntaxTests/modifierAreas/modifiers/valid/empty.sol b/test/libsolidity/syntaxTests/modifierAreas/modifiers/valid/empty.sol new file mode 100644 index 000000000000..a24cdd8893ac --- /dev/null +++ b/test/libsolidity/syntaxTests/modifierAreas/modifiers/valid/empty.sol @@ -0,0 +1,5 @@ +contract C { + modifier A { _; } + apply A {} +} +// ---- diff --git a/test/libsolidity/syntaxTests/modifierAreas/modifiers/valid/many_functions.sol b/test/libsolidity/syntaxTests/modifierAreas/modifiers/valid/many_functions.sol new file mode 100644 index 000000000000..3fead00880e8 --- /dev/null +++ b/test/libsolidity/syntaxTests/modifierAreas/modifiers/valid/many_functions.sol @@ -0,0 +1,12 @@ +contract C { + modifier A { _; } + apply A { + function f() {} + function g() {} + } +} +// ---- +// Warning: (57-72): No visibility specified. Defaulting to "public". +// Warning: (81-96): No visibility specified. Defaulting to "public". +// Warning: (57-72): Function state mutability can be restricted to pure +// Warning: (81-96): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/modifierAreas/modifiers/valid/one_function.sol b/test/libsolidity/syntaxTests/modifierAreas/modifiers/valid/one_function.sol new file mode 100644 index 000000000000..3d1437af4919 --- /dev/null +++ b/test/libsolidity/syntaxTests/modifierAreas/modifiers/valid/one_function.sol @@ -0,0 +1,9 @@ +contract C { + modifier A { _; } + apply A { + function f() {} + } +} +// ---- +// Warning: (57-72): No visibility specified. Defaulting to "public". +// Warning: (57-72): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/modifierAreas/mutability/invalid/function_discrepancy.sol b/test/libsolidity/syntaxTests/modifierAreas/mutability/invalid/function_discrepancy.sol new file mode 100644 index 000000000000..03c296110e5b --- /dev/null +++ b/test/libsolidity/syntaxTests/modifierAreas/mutability/invalid/function_discrepancy.sol @@ -0,0 +1,7 @@ +contract C { + apply pure { + function f() view {} + } +} +// ---- +// ParserError: (51-55): Cannot override modifier area's state mutability. diff --git a/test/libsolidity/syntaxTests/modifierAreas/mutability/invalid/nested_discrepancy.sol b/test/libsolidity/syntaxTests/modifierAreas/mutability/invalid/nested_discrepancy.sol new file mode 100644 index 000000000000..064e2c44aebc --- /dev/null +++ b/test/libsolidity/syntaxTests/modifierAreas/mutability/invalid/nested_discrepancy.sol @@ -0,0 +1,7 @@ +contract C { + apply pure { + apply payable {} + } +} +// ---- +// ParserError: (44-51): Cannot override parent modifier area's state mutability of "pure". diff --git a/test/libsolidity/syntaxTests/modifierAreas/mutability/valid/empty.sol b/test/libsolidity/syntaxTests/modifierAreas/mutability/valid/empty.sol new file mode 100644 index 000000000000..c9e7cc9abb13 --- /dev/null +++ b/test/libsolidity/syntaxTests/modifierAreas/mutability/valid/empty.sol @@ -0,0 +1,4 @@ +contract C { + apply payable {} +} +// ---- diff --git a/test/libsolidity/syntaxTests/modifierAreas/mutability/valid/many_functions.sol b/test/libsolidity/syntaxTests/modifierAreas/mutability/valid/many_functions.sol new file mode 100644 index 000000000000..366b756a956d --- /dev/null +++ b/test/libsolidity/syntaxTests/modifierAreas/mutability/valid/many_functions.sol @@ -0,0 +1,9 @@ +contract C { + apply pure { + function f() {} + function g() {} + } +} +// ---- +// Warning: (38-53): No visibility specified. Defaulting to "public". +// Warning: (62-77): No visibility specified. Defaulting to "public". diff --git a/test/libsolidity/syntaxTests/modifierAreas/mutability/valid/one_function.sol b/test/libsolidity/syntaxTests/modifierAreas/mutability/valid/one_function.sol new file mode 100644 index 000000000000..4c4c1b7f38e2 --- /dev/null +++ b/test/libsolidity/syntaxTests/modifierAreas/mutability/valid/one_function.sol @@ -0,0 +1,7 @@ +contract C { + apply pure { + function f() {} + } +} +// ---- +// Warning: (38-53): No visibility specified. Defaulting to "public". diff --git a/test/libsolidity/syntaxTests/modifierAreas/visibility/invalid/function_discrepancy.sol b/test/libsolidity/syntaxTests/modifierAreas/visibility/invalid/function_discrepancy.sol new file mode 100644 index 000000000000..fb4ff0b39d37 --- /dev/null +++ b/test/libsolidity/syntaxTests/modifierAreas/visibility/invalid/function_discrepancy.sol @@ -0,0 +1,7 @@ +contract C { + apply public { + function f() private {} + } +} +// ---- +// ParserError: (53-60): Cannot override modifier area's visibility. diff --git a/test/libsolidity/syntaxTests/modifierAreas/visibility/invalid/nested_discrepancy.sol b/test/libsolidity/syntaxTests/modifierAreas/visibility/invalid/nested_discrepancy.sol new file mode 100644 index 000000000000..ab9c881a8e83 --- /dev/null +++ b/test/libsolidity/syntaxTests/modifierAreas/visibility/invalid/nested_discrepancy.sol @@ -0,0 +1,7 @@ +contract C { + apply public { + apply private {} + } +} +// ---- +// ParserError: (46-53): Cannot override parent modifier area's visibility of "public". diff --git a/test/libsolidity/syntaxTests/modifierAreas/visibility/valid/empty.sol b/test/libsolidity/syntaxTests/modifierAreas/visibility/valid/empty.sol new file mode 100644 index 000000000000..2eae212de127 --- /dev/null +++ b/test/libsolidity/syntaxTests/modifierAreas/visibility/valid/empty.sol @@ -0,0 +1,4 @@ +contract C { + apply public {} +} +// ---- diff --git a/test/libsolidity/syntaxTests/modifierAreas/visibility/valid/many_functions.sol b/test/libsolidity/syntaxTests/modifierAreas/visibility/valid/many_functions.sol new file mode 100644 index 000000000000..c9640c00e89a --- /dev/null +++ b/test/libsolidity/syntaxTests/modifierAreas/visibility/valid/many_functions.sol @@ -0,0 +1,9 @@ +contract C { + apply internal { + function f() {} + function g() {} + } +} +// ---- +// Warning: (42-57): Function state mutability can be restricted to pure +// Warning: (66-81): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/modifierAreas/visibility/valid/one_function.sol b/test/libsolidity/syntaxTests/modifierAreas/visibility/valid/one_function.sol new file mode 100644 index 000000000000..e691f9aa11c5 --- /dev/null +++ b/test/libsolidity/syntaxTests/modifierAreas/visibility/valid/one_function.sol @@ -0,0 +1,7 @@ +contract C { + apply private { + function f() {} + } +} +// ---- +// Warning: (41-56): Function state mutability can be restricted to pure