From f1da0f7ae9b3d6ab60e3d9152952aea6e572dc0a Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Wed, 14 Aug 2019 15:41:16 +0200 Subject: [PATCH 001/283] Prepares 0.6.0 changelog and documentation. --- Changelog.md | 14 ++++++++++++ docs/060-breaking-changes.rst | 41 +++++++++++++++++++++++++++++++++++ docs/solidity-in-depth.rst | 1 + 3 files changed, 56 insertions(+) create mode 100644 docs/060-breaking-changes.rst diff --git a/Changelog.md b/Changelog.md index d0234a6f6207..5ff25ea643c6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,17 @@ +### 0.6.0 (unreleased) + +Breaking changes: + + +Language Features: + + +Compiler Features: + + +Bugfixes: + + ### 0.5.12 (unreleased) Language Features: diff --git a/docs/060-breaking-changes.rst b/docs/060-breaking-changes.rst new file mode 100644 index 000000000000..e9a24e2f2e2c --- /dev/null +++ b/docs/060-breaking-changes.rst @@ -0,0 +1,41 @@ +******************************** +Solidity v0.6.0 Breaking Changes +******************************** + +This section highlights the main breaking changes introduced in Solidity +version 0.6.0, along with the reasoning behind the changes and how to update +affected code. +For the full list check +`the release changelog `_. + + +Semantic Only Changes +===================== + +This section lists the changes that are semantic-only, thus potentially +hiding new and different behavior in existing code. + + +Semantic and Syntactic Changes +============================== + +This section highlights changes that affect syntax and semantics. + + +How to update your code +======================= + +This section gives detailed instructions on how to update prior code for every breaking change. + + +Deprecated Elements +=================== + +This section lists changes that deprecate prior features or syntax. + + +.. _interoperability_060: + +Interoperability With Older Contracts +===================================== + diff --git a/docs/solidity-in-depth.rst b/docs/solidity-in-depth.rst index ddfddb77b8ea..111a100d7e95 100644 --- a/docs/solidity-in-depth.rst +++ b/docs/solidity-in-depth.rst @@ -19,3 +19,4 @@ If something is missing here, please contact us on assembly.rst miscellaneous.rst 050-breaking-changes.rst + 060-breaking-changes.rst From 9f6fff2120e8614e4993fe5813947f552abf5ea0 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 13 Aug 2019 16:43:25 +0200 Subject: [PATCH 002/283] Replace casting of external functions to address by a member named "address". --- Changelog.md | 1 + docs/060-breaking-changes.rst | 9 ++++ libsolidity/ast/Types.cpp | 5 ++- libsolidity/codegen/CompilerUtils.cpp | 43 ++++++++----------- libsolidity/codegen/ExpressionCompiler.cpp | 7 +++ libsolidity/parsing/Parser.cpp | 8 +++- test/libsolidity/SolidityEndToEndTest.cpp | 19 -------- .../types/external_function_to_address.sol | 11 +++++ .../external_function_type_to_address.sol | 2 +- ...ernal_function_type_to_address_payable.sol | 4 +- .../structs/address_member_access.sol | 9 ++++ .../structs/address_member_declaration.sol | 5 +++ 12 files changed, 72 insertions(+), 51 deletions(-) create mode 100644 test/libsolidity/semanticTests/types/external_function_to_address.sol create mode 100644 test/libsolidity/syntaxTests/structs/address_member_access.sol create mode 100644 test/libsolidity/syntaxTests/structs/address_member_declaration.sol diff --git a/Changelog.md b/Changelog.md index bfc73eb7ca86..aea8d4848641 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ ### 0.6.0 (unreleased) Breaking changes: + * General: Disallow explicit conversions from external function types to ``address`` and add a member called ``address`` to them as replacement. Language Features: diff --git a/docs/060-breaking-changes.rst b/docs/060-breaking-changes.rst index e9a24e2f2e2c..dacd85b16199 100644 --- a/docs/060-breaking-changes.rst +++ b/docs/060-breaking-changes.rst @@ -9,6 +9,14 @@ For the full list check `the release changelog `_. +Syntactic Only Changes +====================== + +This section lists purely syntactic changes that do not affect the behavior of existing code. + +* Conversions from external function types to ``address`` are now disallowed. Instead external + function types have a member called ``address``, similar to the existing ``selector`` member. + Semantic Only Changes ===================== @@ -27,6 +35,7 @@ How to update your code This section gives detailed instructions on how to update prior code for every breaking change. +* Change ``address(f)`` to ``f.address`` for ``f`` being a variable of external function type. Deprecated Elements =================== diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 556347980577..244cfce571ae 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -2726,8 +2726,6 @@ bool FunctionType::operator==(Type const& _other) const BoolResult FunctionType::isExplicitlyConvertibleTo(Type const& _convertTo) const { - if (m_kind == Kind::External && _convertTo == *TypeProvider::address()) - return true; return _convertTo.category() == category(); } @@ -2922,7 +2920,10 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con { MemberList::MemberMap members; if (m_kind == Kind::External) + { members.emplace_back("selector", TypeProvider::fixedBytes(4)); + members.emplace_back("address", TypeProvider::address()); + } if (m_kind != Kind::BareDelegateCall) { if (isPayable()) diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index a275a6e033ac..0e10b3691a08 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -1112,37 +1112,28 @@ void CompilerUtils::convertType( m_context << Instruction::ISZERO << Instruction::ISZERO; break; default: - if (stackTypeCategory == Type::Category::Function && targetTypeCategory == Type::Category::Address) + // we used to allow conversions from function to address + solAssert(!(stackTypeCategory == Type::Category::Function && targetTypeCategory == Type::Category::Address), ""); + if (stackTypeCategory == Type::Category::Function && targetTypeCategory == Type::Category::Function) { FunctionType const& typeOnStack = dynamic_cast(_typeOnStack); - solAssert(typeOnStack.kind() == FunctionType::Kind::External, "Only external function type can be converted."); - - // stack:
- m_context << Instruction::POP; + FunctionType const& targetType = dynamic_cast(_targetType); + solAssert( + typeOnStack.isImplicitlyConvertibleTo(targetType) && + typeOnStack.sizeOnStack() == targetType.sizeOnStack() && + (typeOnStack.kind() == FunctionType::Kind::Internal || typeOnStack.kind() == FunctionType::Kind::External) && + typeOnStack.kind() == targetType.kind(), + "Invalid function type conversion requested." + ); } else - { - if (stackTypeCategory == Type::Category::Function && targetTypeCategory == Type::Category::Function) - { - FunctionType const& typeOnStack = dynamic_cast(_typeOnStack); - FunctionType const& targetType = dynamic_cast(_targetType); - solAssert( - typeOnStack.isImplicitlyConvertibleTo(targetType) && - typeOnStack.sizeOnStack() == targetType.sizeOnStack() && - (typeOnStack.kind() == FunctionType::Kind::Internal || typeOnStack.kind() == FunctionType::Kind::External) && - typeOnStack.kind() == targetType.kind(), - "Invalid function type conversion requested." - ); - } - else - // All other types should not be convertible to non-equal types. - solAssert(_typeOnStack == _targetType, "Invalid type conversion requested."); + // All other types should not be convertible to non-equal types. + solAssert(_typeOnStack == _targetType, "Invalid type conversion requested."); - if (_cleanupNeeded && _targetType.canBeStored() && _targetType.storageBytes() < 32) - m_context - << ((u256(1) << (8 * _targetType.storageBytes())) - 1) - << Instruction::AND; - } + if (_cleanupNeeded && _targetType.canBeStored() && _targetType.storageBytes() < 32) + m_context + << ((u256(1) << (8 * _targetType.storageBytes())) - 1) + << Instruction::AND; break; } diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index c34684840a93..d32bf96b523d 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1338,6 +1338,13 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) /// need to store it as bytes4 utils().leftShiftNumberOnStack(224); } + else if (member == "address") + { + auto const& functionType = dynamic_cast(*_memberAccess.expression().annotation().type); + solAssert(functionType.kind() == FunctionType::Kind::External, ""); + // stack:
+ m_context << Instruction::POP; + } else solAssert( !!_memberAccess.expression().annotation().type->memberType(member), diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index f91cb91eab80..55c73a267e23 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1552,7 +1552,13 @@ ASTPointer Parser::parseLeftHandSideExpression( { m_scanner->next(); nodeFactory.markEndPosition(); - expression = nodeFactory.createNode(expression, expectIdentifierToken()); + if (m_scanner->currentToken() == Token::Address) + { + expression = nodeFactory.createNode(expression, make_shared("address")); + m_scanner->next(); + } + else + expression = nodeFactory.createNode(expression, expectIdentifierToken()); break; } case Token::LParen: diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 903740182ac6..db18bbd4895c 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -11201,25 +11201,6 @@ BOOST_AUTO_TEST_CASE(function_array_cross_calls) ABI_CHECK(callContractFunction("test()"), encodeArgs(u256(5), u256(6), u256(7))); } -BOOST_AUTO_TEST_CASE(external_function_to_address) -{ - char const* sourceCode = R"( - contract C { - function f() public returns (bool) { - return address(this.f) == address(this); - } - function g(function() external cb) public returns (address) { - return address(cb); - } - } - )"; - - compileAndRun(sourceCode, 0, "C"); - ABI_CHECK(callContractFunction("f()"), encodeArgs(true)); - ABI_CHECK(callContractFunction("g(function)", fromHex("00000000000000000000000000000000000004226121ff00000000000000000")), encodeArgs(u160(0x42))); -} - - BOOST_AUTO_TEST_CASE(copy_internal_function_array_to_storage) { char const* sourceCode = R"( diff --git a/test/libsolidity/semanticTests/types/external_function_to_address.sol b/test/libsolidity/semanticTests/types/external_function_to_address.sol new file mode 100644 index 000000000000..fb938d37aaca --- /dev/null +++ b/test/libsolidity/semanticTests/types/external_function_to_address.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (bool) { + return this.f.address == address(this); + } + function g(function() external cb) public returns (address) { + return cb.address; + } +} +// ---- +// f() -> true +// g(function): hex"00000000000000000000000000000000000004226121ff00000000000000000" -> 0x42 diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol index b86425dbc2c9..99b5eb2325f3 100644 --- a/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol +++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol @@ -1,5 +1,5 @@ contract C { function f() public view returns (address) { - return address(this.f); + return this.f.address; } } diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address_payable.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address_payable.sol index adffb14b358f..0cd7764f5b96 100644 --- a/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address_payable.sol +++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address_payable.sol @@ -1,7 +1,7 @@ contract C { function f() public view returns (address payable) { - return address(this.f); + return this.f.address; } } // ---- -// TypeError: (85-100): Return argument type address is not implicitly convertible to expected type (type of first return variable) address payable. +// TypeError: (85-99): Return argument type address is not implicitly convertible to expected type (type of first return variable) address payable. diff --git a/test/libsolidity/syntaxTests/structs/address_member_access.sol b/test/libsolidity/syntaxTests/structs/address_member_access.sol new file mode 100644 index 000000000000..cf5170bf460b --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/address_member_access.sol @@ -0,0 +1,9 @@ +contract C { + struct S { uint a; } + function f() public pure returns(address) { + S memory s = S(42); + return s.address; + } +} +// ---- +// TypeError: (129-138): Member "address" not found or not visible after argument-dependent lookup in struct C.S memory. diff --git a/test/libsolidity/syntaxTests/structs/address_member_declaration.sol b/test/libsolidity/syntaxTests/structs/address_member_declaration.sol new file mode 100644 index 000000000000..2e654187b67c --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/address_member_declaration.sol @@ -0,0 +1,5 @@ +contract C { + struct S { uint address; } +} +// ---- +// ParserError: (33-40): Expected identifier but got 'address' From 80199ded793a9c6ed146a179967594cfa15ab86f Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 15 Aug 2019 13:57:04 +0200 Subject: [PATCH 003/283] More documentation updates. --- docs/060-breaking-changes.rst | 2 +- docs/types/value-types.rst | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/060-breaking-changes.rst b/docs/060-breaking-changes.rst index dacd85b16199..c6dd4112411e 100644 --- a/docs/060-breaking-changes.rst +++ b/docs/060-breaking-changes.rst @@ -35,7 +35,7 @@ How to update your code This section gives detailed instructions on how to update prior code for every breaking change. -* Change ``address(f)`` to ``f.address`` for ``f`` being a variable of external function type. +* Change ``address(f)`` to ``f.address`` for ``f`` being of external function type. Deprecated Elements =================== diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index 0b9d6ad90419..5f7337aaf1a7 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -582,9 +582,6 @@ do not have a default. Conversions: -A value of external function type can be explicitly converted to ``address`` -resulting in the address of the contract of the function. - A function type ``A`` is implicitly convertible to a function type ``B`` if and only if their parameter types are identical, their return types are identical, their internal/external property is identical and the state mutability of ``A`` @@ -616,8 +613,9 @@ just use ``f``, if you want to use its external form, use ``this.f``. Members: -Public (or external) functions have the following members: +External (or public) functions have the following members: +* ``.address`` returns the address of the contract of the function. * ``.selector`` returns the :ref:`ABI function selector ` * ``.gas(uint)`` returns a callable function object which, when called, will send the specified amount of gas to the target function. See :ref:`External Function Calls ` for more information. * ``.value(uint)`` returns a callable function object which, when called, will send the specified amount of wei to the target function. See :ref:`External Function Calls ` for more information. @@ -629,6 +627,7 @@ Example that shows how to use the members:: contract Example { function f() public payable returns (bytes4) { + assert(this.f.address == address(this)); return this.f.selector; } From 42f30981db1ab75b32de895e215c92bc52650ae1 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 15 Aug 2019 13:57:12 +0200 Subject: [PATCH 004/283] Add unimplemented assertion to IR generation when accessing address member of external function types. --- libsolidity/codegen/ir/IRGeneratorForStatements.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 5dcb811cceba..2258707faef8 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -718,6 +718,10 @@ void IRGeneratorForStatements::endVisit(MemberAccess const& _memberAccess) { solUnimplementedAssert(false, ""); } + else if (member == "address") + { + solUnimplementedAssert(false, ""); + } else solAssert( !!_memberAccess.expression().annotation().type->memberType(member), From 20b23e124be8f3d0d914e1b4bf8fc42c37a401bc Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 15 Aug 2019 14:01:07 +0200 Subject: [PATCH 005/283] Add test case. --- .../syntaxTests/functionTypes/conversion_to_address.sol | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 test/libsolidity/syntaxTests/functionTypes/conversion_to_address.sol diff --git a/test/libsolidity/syntaxTests/functionTypes/conversion_to_address.sol b/test/libsolidity/syntaxTests/functionTypes/conversion_to_address.sol new file mode 100644 index 000000000000..6bc3e6c44b82 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/conversion_to_address.sol @@ -0,0 +1,7 @@ +contract C { + function f() public view returns (address) { + return address(this.f); + } +} +// ---- +// TypeError: (77-92): Explicit type conversion not allowed from "function () view external returns (address)" to "address". From 4354ef2ef48227c322d0dd9ad57ab7195d33c722 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 15 Aug 2019 18:46:44 +0200 Subject: [PATCH 006/283] Add update suggestion. --- libsolidity/analysis/TypeChecker.cpp | 18 +++++++++++++++++- .../functionTypes/conversion_to_address.sol | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index b5abe59f4dfe..553aa0dfb62e 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1478,12 +1478,28 @@ TypePointer TypeChecker::typeCheckTypeConversionAndRetrieveReturnType( variableDeclaration->location() ); m_errorReporter.typeError( - _functionCall.location(), ssl, + _functionCall.location(), + ssl, "Explicit type conversion not allowed from non-payable \"address\" to \"" + resultType->toString() + "\", which has a payable fallback function." ); } + else if ( + auto const* functionType = dynamic_cast(argType); + functionType && + functionType->kind() == FunctionType::Kind::External && + resultType->category() == Type::Category::Address + ) + m_errorReporter.typeError( + _functionCall.location(), + "Explicit type conversion not allowed from \"" + + argType->toString() + + "\" to \"" + + resultType->toString() + + "\". To obtain the address of the contract of the function, " + + "you can use the .address member of the function." + ); else m_errorReporter.typeError( _functionCall.location(), diff --git a/test/libsolidity/syntaxTests/functionTypes/conversion_to_address.sol b/test/libsolidity/syntaxTests/functionTypes/conversion_to_address.sol index 6bc3e6c44b82..703d6c89f201 100644 --- a/test/libsolidity/syntaxTests/functionTypes/conversion_to_address.sol +++ b/test/libsolidity/syntaxTests/functionTypes/conversion_to_address.sol @@ -4,4 +4,4 @@ contract C { } } // ---- -// TypeError: (77-92): Explicit type conversion not allowed from "function () view external returns (address)" to "address". +// TypeError: (77-92): Explicit type conversion not allowed from "function () view external returns (address)" to "address". To obtain the address of the contract of the function, you can use the .address member of the function. From 24716404f8d9f714f43a3bea51f46f2fc5ccf769 Mon Sep 17 00:00:00 2001 From: Mathias Baumann Date: Tue, 13 Aug 2019 13:00:46 +0200 Subject: [PATCH 007/283] Parse override keyword --- liblangutil/Token.h | 2 +- libsolidity/ast/AST.h | 34 ++ libsolidity/ast/ASTForward.h | 1 + libsolidity/ast/ASTJsonConverter.cpp | 2 + libsolidity/ast/ASTPrinter.cpp | 12 + libsolidity/ast/ASTPrinter.h | 2 + libsolidity/ast/ASTVisitor.h | 4 + libsolidity/ast/AST_accept.h | 18 + libsolidity/parsing/Parser.cpp | 55 +- libsolidity/parsing/Parser.h | 4 +- .../standard_only_ast_requested/output.json | 2 +- test/libsolidity/ASTJSON/address_payable.json | 6 + .../ASTJSON/address_payable_legacy.json | 6 + test/libsolidity/ASTJSON/array_type_name.json | 1 + test/libsolidity/ASTJSON/array_type_name.sol | 2 + .../ASTJSON/array_type_name_legacy.json | 1 + test/libsolidity/ASTJSON/constructor.json | 1 + test/libsolidity/ASTJSON/constructor.sol | 2 + .../ASTJSON/constructor_legacy.json | 1 + test/libsolidity/ASTJSON/documentation.json | 1 + test/libsolidity/ASTJSON/documentation.sol | 2 + .../ASTJSON/documentation_legacy.json | 1 + test/libsolidity/ASTJSON/fallback.json | 1 + test/libsolidity/ASTJSON/fallback.sol | 2 + test/libsolidity/ASTJSON/fallback_legacy.json | 1 + .../libsolidity/ASTJSON/fallback_payable.json | 1 + test/libsolidity/ASTJSON/fallback_payable.sol | 2 + .../ASTJSON/fallback_payable_legacy.json | 1 + test/libsolidity/ASTJSON/function_type.json | 5 + .../ASTJSON/function_type_legacy.json | 5 + .../long_type_name_binary_operation.json | 2 + .../long_type_name_binary_operation.sol | 2 + ...ong_type_name_binary_operation_legacy.json | 2 + .../ASTJSON/long_type_name_identifier.json | 3 + .../ASTJSON/long_type_name_identifier.sol | 2 + .../long_type_name_identifier_legacy.json | 3 + .../ASTJSON/modifier_definition.json | 2 + .../ASTJSON/modifier_definition.sol | 2 + .../ASTJSON/modifier_definition_legacy.json | 2 + .../ASTJSON/modifier_invocation.json | 2 + .../ASTJSON/modifier_invocation.sol | 2 + .../ASTJSON/modifier_invocation_legacy.json | 2 + test/libsolidity/ASTJSON/non_utf8.json | 2 + test/libsolidity/ASTJSON/non_utf8.sol | 2 + test/libsolidity/ASTJSON/non_utf8_legacy.json | 2 + test/libsolidity/ASTJSON/override.json | 337 ++++++++++++ test/libsolidity/ASTJSON/override.sol | 13 + test/libsolidity/ASTJSON/override_legacy.json | 492 ++++++++++++++++++ test/libsolidity/ASTJSON/short_type_name.json | 2 + test/libsolidity/ASTJSON/short_type_name.sol | 2 + .../ASTJSON/short_type_name_legacy.json | 2 + .../ASTJSON/short_type_name_ref.json | 2 + .../ASTJSON/short_type_name_ref.sol | 2 + .../ASTJSON/short_type_name_ref_legacy.json | 2 + test/libsolidity/ASTJSON/source_location.json | 2 + test/libsolidity/ASTJSON/source_location.sol | 2 + .../ASTJSON/source_location_legacy.json | 2 + test/libsolidity/SolidityParser.cpp | 1 - .../override/detect_double_override.sol | 7 + .../inheritance/override/override.sol | 5 + .../override/override_empty_list.sol | 10 + .../override/override_multiple.sol | 9 + .../override/override_multiple_fail1.sol | 8 + .../override/override_multiple_fail2.sol | 8 + .../override/override_multiple_fail3.sol | 8 + .../override/override_multiple_fail4.sol | 8 + 66 files changed, 1127 insertions(+), 7 deletions(-) create mode 100644 test/libsolidity/ASTJSON/override.json create mode 100644 test/libsolidity/ASTJSON/override.sol create mode 100644 test/libsolidity/ASTJSON/override_legacy.json create mode 100644 test/libsolidity/syntaxTests/inheritance/override/detect_double_override.sol create mode 100644 test/libsolidity/syntaxTests/inheritance/override/override.sol create mode 100644 test/libsolidity/syntaxTests/inheritance/override/override_empty_list.sol create mode 100644 test/libsolidity/syntaxTests/inheritance/override/override_multiple.sol create mode 100644 test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail1.sol create mode 100644 test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail2.sol create mode 100644 test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail3.sol create mode 100644 test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail4.sol diff --git a/liblangutil/Token.h b/liblangutil/Token.h index 35d4f76f339d..c725c43bded3 100644 --- a/liblangutil/Token.h +++ b/liblangutil/Token.h @@ -171,6 +171,7 @@ namespace langutil K(Memory, "memory", 0) \ K(Modifier, "modifier", 0) \ K(New, "new", 0) \ + K(Override, "override", 0) \ K(Payable, "payable", 0) \ K(Public, "public", 0) \ K(Pragma, "pragma", 0) \ @@ -248,7 +249,6 @@ namespace langutil K(Mutable, "mutable", 0) \ K(NullLiteral, "null", 0) \ K(Of, "of", 0) \ - K(Override, "override", 0) \ K(Partial, "partial", 0) \ K(Promise, "promise", 0) \ K(Reference, "reference", 0) \ diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index b84ad2c19f8c..764a5d9fe5f6 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -604,6 +604,32 @@ class CallableDeclaration: public Declaration, public VariableScope ASTPointer m_returnParameters; }; +/** + * Function override specifier. Consists of a single override keyword + * potentially followed by a parenthesized list of base contract names. + */ +class OverrideSpecifier: public ASTNode +{ +public: + OverrideSpecifier( + SourceLocation const& _location, + std::vector> const& _overrides + ): + ASTNode(_location), + m_overrides(_overrides) + { + } + + void accept(ASTVisitor& _visitor) override; + void accept(ASTConstVisitor& _visitor) const override; + + /// @returns the list of specific overrides, if any + std::vector> const& overrides() const { return m_overrides; } + +protected: + std::vector> m_overrides; +}; + class FunctionDefinition: public CallableDeclaration, public Documented, public ImplementationOptional { public: @@ -613,6 +639,7 @@ class FunctionDefinition: public CallableDeclaration, public Documented, public Declaration::Visibility _visibility, StateMutability _stateMutability, bool _isConstructor, + ASTPointer const& _overrides, ASTPointer const& _documentation, ASTPointer const& _parameters, std::vector> const& _modifiers, @@ -624,6 +651,7 @@ class FunctionDefinition: public CallableDeclaration, public Documented, public ImplementationOptional(_body != nullptr), m_stateMutability(_stateMutability), m_isConstructor(_isConstructor), + m_overrides(_overrides), m_functionModifiers(_modifiers), m_body(_body) {} @@ -633,6 +661,7 @@ class FunctionDefinition: public CallableDeclaration, public Documented, public StateMutability stateMutability() const { return m_stateMutability; } bool isConstructor() const { return m_isConstructor; } + ASTPointer const& overrides() const { return m_overrides; } bool isFallback() const { return !m_isConstructor && name().empty(); } bool isPayable() const { return m_stateMutability == StateMutability::Payable; } std::vector> const& modifiers() const { return m_functionModifiers; } @@ -661,6 +690,7 @@ class FunctionDefinition: public CallableDeclaration, public Documented, public private: StateMutability m_stateMutability; bool m_isConstructor; + ASTPointer m_overrides; std::vector> m_functionModifiers; ASTPointer m_body; }; @@ -683,6 +713,7 @@ class VariableDeclaration: public Declaration bool _isStateVar = false, bool _isIndexed = false, bool _isConstant = false, + ASTPointer const& _overrides = nullptr, Location _referenceLocation = Location::Unspecified ): Declaration(_sourceLocation, _name, _visibility), @@ -691,6 +722,7 @@ class VariableDeclaration: public Declaration m_isStateVariable(_isStateVar), m_isIndexed(_isIndexed), m_isConstant(_isConstant), + m_overrides(_overrides), m_location(_referenceLocation) {} void accept(ASTVisitor& _visitor) override; @@ -730,6 +762,7 @@ class VariableDeclaration: public Declaration bool isStateVariable() const { return m_isStateVariable; } bool isIndexed() const { return m_isIndexed; } bool isConstant() const { return m_isConstant; } + ASTPointer const& overrides() const { return m_overrides; } Location referenceLocation() const { return m_location; } /// @returns a set of allowed storage locations for the variable. std::set allowedDataLocations() const; @@ -753,6 +786,7 @@ class VariableDeclaration: public Declaration bool m_isStateVariable; ///< Whether or not this is a contract state variable bool m_isIndexed; ///< Whether this is an indexed variable (used by events). bool m_isConstant; ///< Whether the variable is a compile-time constant. + ASTPointer m_overrides; ///< Contains the override specifier node Location m_location; ///< Location of the variable if it is of reference type. }; diff --git a/libsolidity/ast/ASTForward.h b/libsolidity/ast/ASTForward.h index aad4ad558b1f..db6952694842 100644 --- a/libsolidity/ast/ASTForward.h +++ b/libsolidity/ast/ASTForward.h @@ -39,6 +39,7 @@ class PragmaDirective; class ImportDirective; class Declaration; class CallableDeclaration; +class OverrideSpecifier; class ContractDefinition; class InheritanceSpecifier; class UsingForDirective; diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index 669b46d5339a..a81ec3ac95c1 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -334,6 +334,7 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node) make_pair("stateMutability", stateMutabilityToString(_node.stateMutability())), make_pair("superFunction", idOrNull(_node.annotation().superFunction)), make_pair("visibility", Declaration::visibilityToString(_node.visibility())), + make_pair("overrides", _node.overrides() ? toJson(_node.overrides()->overrides()) : Json::nullValue), make_pair("parameters", toJson(_node.parameterList())), make_pair("returnParameters", toJson(*_node.returnParameterList())), make_pair("modifiers", toJson(_node.modifiers())), @@ -355,6 +356,7 @@ bool ASTJsonConverter::visit(VariableDeclaration const& _node) make_pair("constant", _node.isConstant()), make_pair("stateVariable", _node.isStateVariable()), make_pair("storageLocation", location(_node.referenceLocation())), + make_pair("overrides", _node.overrides() ? toJson(_node.overrides()->overrides()) : Json::nullValue), make_pair("visibility", Declaration::visibilityToString(_node.visibility())), make_pair("value", _node.value() ? toJson(*_node.value()) : Json::nullValue), make_pair("scope", idOrNull(_node.scope())), diff --git a/libsolidity/ast/ASTPrinter.cpp b/libsolidity/ast/ASTPrinter.cpp index 7d77ff7b9af3..1d9f40876845 100644 --- a/libsolidity/ast/ASTPrinter.cpp +++ b/libsolidity/ast/ASTPrinter.cpp @@ -111,6 +111,13 @@ bool ASTPrinter::visit(ParameterList const& _node) return goDeeper(); } +bool ASTPrinter::visit(OverrideSpecifier const& _node) +{ + writeLine("OverrideSpecifier"); + printSourcePart(_node); + return goDeeper(); +} + bool ASTPrinter::visit(FunctionDefinition const& _node) { writeLine( @@ -432,6 +439,11 @@ void ASTPrinter::endVisit(ParameterList const&) m_indentation--; } +void ASTPrinter::endVisit(OverrideSpecifier const&) +{ + m_indentation--; +} + void ASTPrinter::endVisit(FunctionDefinition const&) { m_indentation--; diff --git a/libsolidity/ast/ASTPrinter.h b/libsolidity/ast/ASTPrinter.h index 2e9cb4fc6ec8..697db4378ee1 100644 --- a/libsolidity/ast/ASTPrinter.h +++ b/libsolidity/ast/ASTPrinter.h @@ -56,6 +56,7 @@ class ASTPrinter: public ASTConstVisitor bool visit(EnumDefinition const& _node) override; bool visit(EnumValue const& _node) override; bool visit(ParameterList const& _node) override; + bool visit(OverrideSpecifier const& _node) override; bool visit(FunctionDefinition const& _node) override; bool visit(VariableDeclaration const& _node) override; bool visit(ModifierDefinition const& _node) override; @@ -101,6 +102,7 @@ class ASTPrinter: public ASTConstVisitor void endVisit(EnumDefinition const&) override; void endVisit(EnumValue const&) override; void endVisit(ParameterList const&) override; + void endVisit(OverrideSpecifier const&) override; void endVisit(FunctionDefinition const&) override; void endVisit(VariableDeclaration const&) override; void endVisit(ModifierDefinition const&) override; diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h index 5b97bb06a13d..6184e5f4270e 100644 --- a/libsolidity/ast/ASTVisitor.h +++ b/libsolidity/ast/ASTVisitor.h @@ -54,6 +54,7 @@ class ASTVisitor virtual bool visit(EnumDefinition& _node) { return visitNode(_node); } virtual bool visit(EnumValue& _node) { return visitNode(_node); } virtual bool visit(ParameterList& _node) { return visitNode(_node); } + virtual bool visit(OverrideSpecifier& _node) { return visitNode(_node); } virtual bool visit(FunctionDefinition& _node) { return visitNode(_node); } virtual bool visit(VariableDeclaration& _node) { return visitNode(_node); } virtual bool visit(ModifierDefinition& _node) { return visitNode(_node); } @@ -100,6 +101,7 @@ class ASTVisitor virtual void endVisit(EnumDefinition& _node) { endVisitNode(_node); } virtual void endVisit(EnumValue& _node) { endVisitNode(_node); } virtual void endVisit(ParameterList& _node) { endVisitNode(_node); } + virtual void endVisit(OverrideSpecifier& _node) { endVisitNode(_node); } virtual void endVisit(FunctionDefinition& _node) { endVisitNode(_node); } virtual void endVisit(VariableDeclaration& _node) { endVisitNode(_node); } virtual void endVisit(ModifierDefinition& _node) { endVisitNode(_node); } @@ -159,6 +161,7 @@ class ASTConstVisitor virtual bool visit(EnumDefinition const& _node) { return visitNode(_node); } virtual bool visit(EnumValue const& _node) { return visitNode(_node); } virtual bool visit(ParameterList const& _node) { return visitNode(_node); } + virtual bool visit(OverrideSpecifier const& _node) { return visitNode(_node); } virtual bool visit(FunctionDefinition const& _node) { return visitNode(_node); } virtual bool visit(VariableDeclaration const& _node) { return visitNode(_node); } virtual bool visit(ModifierDefinition const& _node) { return visitNode(_node); } @@ -205,6 +208,7 @@ class ASTConstVisitor virtual void endVisit(EnumDefinition const& _node) { endVisitNode(_node); } virtual void endVisit(EnumValue const& _node) { endVisitNode(_node); } virtual void endVisit(ParameterList const& _node) { endVisitNode(_node); } + virtual void endVisit(OverrideSpecifier const& _node) { endVisitNode(_node); } virtual void endVisit(FunctionDefinition const& _node) { endVisitNode(_node); } virtual void endVisit(VariableDeclaration const& _node) { endVisitNode(_node); } virtual void endVisit(ModifierDefinition const& _node) { endVisitNode(_node); } diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h index 5538180d9035..a95c22d7b544 100644 --- a/libsolidity/ast/AST_accept.h +++ b/libsolidity/ast/AST_accept.h @@ -187,10 +187,26 @@ void ParameterList::accept(ASTConstVisitor& _visitor) const _visitor.endVisit(*this); } +void OverrideSpecifier::accept(ASTVisitor& _visitor) +{ + if (_visitor.visit(*this)) + listAccept(m_overrides, _visitor); + _visitor.endVisit(*this); +} + +void OverrideSpecifier::accept(ASTConstVisitor& _visitor) const +{ + if (_visitor.visit(*this)) + listAccept(m_overrides, _visitor); + _visitor.endVisit(*this); +} + void FunctionDefinition::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) { + if (m_overrides) + m_overrides->accept(_visitor); m_parameters->accept(_visitor); if (m_returnParameters) m_returnParameters->accept(_visitor); @@ -205,6 +221,8 @@ void FunctionDefinition::accept(ASTConstVisitor& _visitor) const { if (_visitor.visit(*this)) { + if (m_overrides) + m_overrides->accept(_visitor); m_parameters->accept(_visitor); if (m_returnParameters) m_returnParameters->accept(_visitor); diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 55c73a267e23..b358e4a9478d 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -382,6 +382,36 @@ Declaration::Visibility Parser::parseVisibilitySpecifier() return visibility; } +ASTPointer Parser::parseOverrideSpecifier() +{ + solAssert(m_scanner->currentToken() == Token::Override, ""); + + ASTNodeFactory nodeFactory(*this); + std::vector> overrides; + + nodeFactory.markEndPosition(); + m_scanner->next(); + + if (m_scanner->currentToken() == Token::LParen) + { + m_scanner->next(); + while (true) + { + overrides.push_back(parseUserDefinedTypeName()); + + if (m_scanner->currentToken() == Token::RParen) + break; + + expectToken(Token::Comma); + } + + nodeFactory.markEndPosition(); + expectToken(Token::RParen); + } + + return nodeFactory.createNode(move(overrides)); +} + StateMutability Parser::parseStateMutability() { StateMutability stateMutability(StateMutability::NonPayable); @@ -411,12 +441,13 @@ StateMutability Parser::parseStateMutability() return stateMutability; } -Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers) +Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _onlyFuncType, bool _allowFuncDef) { RecursionGuard recursionGuard(*this); FunctionHeaderParserResult result; result.isConstructor = false; + result.overrides = nullptr; if (m_scanner->currentToken() == Token::Constructor) result.isConstructor = true; @@ -426,7 +457,7 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyN if (result.isConstructor) result.name = make_shared(); - else if (_forceEmptyName || m_scanner->currentToken() == Token::LParen) + else if (_onlyFuncType || m_scanner->currentToken() == Token::LParen) result.name = make_shared(); else if (m_scanner->currentToken() == Token::Constructor) fatalParserError(string( @@ -443,7 +474,7 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyN while (true) { Token token = m_scanner->currentToken(); - if (_allowModifiers && token == Token::Identifier) + if (_allowFuncDef && token == Token::Identifier) { // If the name is empty (and this is not a constructor), // then this can either be a modifier (fallback function declaration) @@ -493,6 +524,13 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _forceEmptyN else result.stateMutability = parseStateMutability(); } + else if (_allowFuncDef && token == Token::Override) + { + if (result.overrides) + parserError("Override already specified."); + + result.overrides = parseOverrideSpecifier(); + } else break; } @@ -521,6 +559,7 @@ ASTPointer Parser::parseFunctionDefinitionOrFunctionTypeStateVariable() header.isConstructor || !header.modifiers.empty() || !header.name->empty() || + header.overrides || m_scanner->currentToken() == Token::Semicolon || m_scanner->currentToken() == Token::LBrace ) @@ -540,6 +579,7 @@ ASTPointer Parser::parseFunctionDefinitionOrFunctionTypeStateVariable() header.visibility, header.stateMutability, header.isConstructor, + header.overrides, docstring, header.parameters, header.modifiers, @@ -637,6 +677,7 @@ ASTPointer Parser::parseVariableDeclaration( } bool isIndexed = false; bool isDeclaredConst = false; + ASTPointer overrides = nullptr; Declaration::Visibility visibility(Declaration::Visibility::Default); VariableDeclaration::Location location = VariableDeclaration::Location::Unspecified; ASTPointer identifier; @@ -659,6 +700,13 @@ ASTPointer Parser::parseVariableDeclaration( else visibility = parseVisibilitySpecifier(); } + else if (_options.isStateVariable && token == Token::Override) + { + if (overrides) + parserError("Override already specified."); + + overrides = parseOverrideSpecifier(); + } else { if (_options.allowIndexed && token == Token::Indexed) @@ -724,6 +772,7 @@ ASTPointer Parser::parseVariableDeclaration( _options.isStateVariable, isIndexed, isDeclaredConst, + overrides, location ); } diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index cb3d75f51db8..b0e1c6716516 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -71,6 +71,7 @@ class Parser: public langutil::ParserBase struct FunctionHeaderParserResult { bool isConstructor; + ASTPointer overrides; ASTPointer name; ASTPointer parameters; ASTPointer returnParameters; @@ -88,8 +89,9 @@ class Parser: public langutil::ParserBase ASTPointer parseContractDefinition(); ASTPointer parseInheritanceSpecifier(); Declaration::Visibility parseVisibilitySpecifier(); + ASTPointer parseOverrideSpecifier(); StateMutability parseStateMutability(); - FunctionHeaderParserResult parseFunctionHeader(bool _forceEmptyName, bool _allowModifiers); + FunctionHeaderParserResult parseFunctionHeader(bool _onlyFuncType, bool _allowFuncDef); ASTPointer parseFunctionDefinitionOrFunctionTypeStateVariable(); ASTPointer parseFunctionDefinition(ASTString const* _contractName); ASTPointer parseStructDefinition(); diff --git a/test/cmdlineTests/standard_only_ast_requested/output.json b/test/cmdlineTests/standard_only_ast_requested/output.json index b884ab7dffe1..212429661f37 100644 --- a/test/cmdlineTests/standard_only_ast_requested/output.json +++ b/test/cmdlineTests/standard_only_ast_requested/output.json @@ -1 +1 @@ -{"sources":{"A":{"ast":{"absolutePath":"A","exportedSymbols":{"C":[6]},"id":7,"nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity",">=","0.0"],"nodeType":"PragmaDirective","src":"0:22:0"},{"baseContracts":[],"contractDependencies":[],"contractKind":"contract","documentation":null,"fullyImplemented":true,"id":6,"linearizedBaseContracts":[6],"name":"C","nodeType":"ContractDefinition","nodes":[{"body":{"id":4,"nodeType":"Block","src":"61:2:0","statements":[]},"documentation":null,"id":5,"implemented":true,"kind":"function","modifiers":[],"name":"f","nodeType":"FunctionDefinition","parameters":{"id":2,"nodeType":"ParameterList","parameters":[],"src":"46:2:0"},"returnParameters":{"id":3,"nodeType":"ParameterList","parameters":[],"src":"61:0:0"},"scope":6,"src":"36:27:0","stateMutability":"pure","superFunction":null,"visibility":"public"}],"scope":7,"src":"23:42:0"}],"src":"0:65:0"},"id":0}}} +{"sources":{"A":{"ast":{"absolutePath":"A","exportedSymbols":{"C":[6]},"id":7,"nodeType":"SourceUnit","nodes":[{"id":1,"literals":["solidity",">=","0.0"],"nodeType":"PragmaDirective","src":"0:22:0"},{"baseContracts":[],"contractDependencies":[],"contractKind":"contract","documentation":null,"fullyImplemented":true,"id":6,"linearizedBaseContracts":[6],"name":"C","nodeType":"ContractDefinition","nodes":[{"body":{"id":4,"nodeType":"Block","src":"61:2:0","statements":[]},"documentation":null,"id":5,"implemented":true,"kind":"function","modifiers":[],"name":"f","nodeType":"FunctionDefinition","overrides":null,"parameters":{"id":2,"nodeType":"ParameterList","parameters":[],"src":"46:2:0"},"returnParameters":{"id":3,"nodeType":"ParameterList","parameters":[],"src":"61:0:0"},"scope":6,"src":"36:27:0","stateMutability":"pure","superFunction":null,"visibility":"public"}],"scope":7,"src":"23:42:0"}],"src":"0:65:0"},"id":0}}} diff --git a/test/libsolidity/ASTJSON/address_payable.json b/test/libsolidity/ASTJSON/address_payable.json index c8b71628cbad..88ce272dc705 100644 --- a/test/libsolidity/ASTJSON/address_payable.json +++ b/test/libsolidity/ASTJSON/address_payable.json @@ -31,6 +31,7 @@ "id" : 4, "name" : "m", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 37, "src" : "17:44:1", "stateVariable" : true, @@ -99,6 +100,7 @@ "id" : 12, "name" : "a", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 35, "src" : "144:17:1", "stateVariable" : false, @@ -239,6 +241,7 @@ "id" : 22, "name" : "c", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 35, "src" : "197:9:1", "stateVariable" : false, @@ -467,6 +470,7 @@ "modifiers" : [], "name" : "f", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 7, @@ -478,6 +482,7 @@ "id" : 6, "name" : "arg", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 36, "src" : "78:19:1", "stateVariable" : false, @@ -517,6 +522,7 @@ "id" : 9, "name" : "r", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 36, "src" : "115:17:1", "stateVariable" : false, diff --git a/test/libsolidity/ASTJSON/address_payable_legacy.json b/test/libsolidity/ASTJSON/address_payable_legacy.json index 8abebce0890e..a2758b16bff5 100644 --- a/test/libsolidity/ASTJSON/address_payable_legacy.json +++ b/test/libsolidity/ASTJSON/address_payable_legacy.json @@ -40,6 +40,7 @@ { "constant" : false, "name" : "m", + "overrides" : null, "scope" : 37, "stateVariable" : true, "storageLocation" : "default", @@ -99,6 +100,7 @@ null ], "name" : "f", + "overrides" : null, "scope" : 37, "stateMutability" : "nonpayable", "superFunction" : null, @@ -114,6 +116,7 @@ { "constant" : false, "name" : "arg", + "overrides" : null, "scope" : 36, "stateVariable" : false, "storageLocation" : "default", @@ -152,6 +155,7 @@ { "constant" : false, "name" : "r", + "overrides" : null, "scope" : 36, "stateVariable" : false, "storageLocation" : "default", @@ -200,6 +204,7 @@ { "constant" : false, "name" : "a", + "overrides" : null, "scope" : 35, "stateVariable" : false, "storageLocation" : "default", @@ -352,6 +357,7 @@ { "constant" : false, "name" : "c", + "overrides" : null, "scope" : 35, "stateVariable" : false, "storageLocation" : "default", diff --git a/test/libsolidity/ASTJSON/array_type_name.json b/test/libsolidity/ASTJSON/array_type_name.json index e3a3bea94629..bc783ef88010 100644 --- a/test/libsolidity/ASTJSON/array_type_name.json +++ b/test/libsolidity/ASTJSON/array_type_name.json @@ -31,6 +31,7 @@ "id" : 3, "name" : "i", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 4, "src" : "13:8:1", "stateVariable" : true, diff --git a/test/libsolidity/ASTJSON/array_type_name.sol b/test/libsolidity/ASTJSON/array_type_name.sol index 202ecf02b5d8..97ed03510af6 100644 --- a/test/libsolidity/ASTJSON/array_type_name.sol +++ b/test/libsolidity/ASTJSON/array_type_name.sol @@ -1 +1,3 @@ contract C { uint[] i; } + +// ---- diff --git a/test/libsolidity/ASTJSON/array_type_name_legacy.json b/test/libsolidity/ASTJSON/array_type_name_legacy.json index 80feb344b590..749a49a69b25 100644 --- a/test/libsolidity/ASTJSON/array_type_name_legacy.json +++ b/test/libsolidity/ASTJSON/array_type_name_legacy.json @@ -40,6 +40,7 @@ { "constant" : false, "name" : "i", + "overrides" : null, "scope" : 4, "stateVariable" : true, "storageLocation" : "default", diff --git a/test/libsolidity/ASTJSON/constructor.json b/test/libsolidity/ASTJSON/constructor.json index b0bc420195a4..d6a0d47ba92f 100644 --- a/test/libsolidity/ASTJSON/constructor.json +++ b/test/libsolidity/ASTJSON/constructor.json @@ -41,6 +41,7 @@ "modifiers" : [], "name" : "", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 1, diff --git a/test/libsolidity/ASTJSON/constructor.sol b/test/libsolidity/ASTJSON/constructor.sol index 79d04eb5a4e3..f89ac45b4135 100644 --- a/test/libsolidity/ASTJSON/constructor.sol +++ b/test/libsolidity/ASTJSON/constructor.sol @@ -2,3 +2,5 @@ contract C { constructor() public { } } + +// ---- diff --git a/test/libsolidity/ASTJSON/constructor_legacy.json b/test/libsolidity/ASTJSON/constructor_legacy.json index 0617073e3751..c5e1d3a142b4 100644 --- a/test/libsolidity/ASTJSON/constructor_legacy.json +++ b/test/libsolidity/ASTJSON/constructor_legacy.json @@ -47,6 +47,7 @@ null ], "name" : "", + "overrides" : null, "scope" : 5, "stateMutability" : "nonpayable", "superFunction" : null, diff --git a/test/libsolidity/ASTJSON/documentation.json b/test/libsolidity/ASTJSON/documentation.json index ce1e0b57aa12..a761c836c84c 100644 --- a/test/libsolidity/ASTJSON/documentation.json +++ b/test/libsolidity/ASTJSON/documentation.json @@ -151,6 +151,7 @@ "modifiers" : [], "name" : "fn", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 11, diff --git a/test/libsolidity/ASTJSON/documentation.sol b/test/libsolidity/ASTJSON/documentation.sol index e65af9b44958..5c5fe7d2b650 100644 --- a/test/libsolidity/ASTJSON/documentation.sol +++ b/test/libsolidity/ASTJSON/documentation.sol @@ -15,3 +15,5 @@ contract C { /** Some comment on mod.*/ modifier mod() { _; } /** Some comment on fn.*/ function fn() public {} } + +// ---- diff --git a/test/libsolidity/ASTJSON/documentation_legacy.json b/test/libsolidity/ASTJSON/documentation_legacy.json index 0277902f8dd3..1dc3d9a4a359 100644 --- a/test/libsolidity/ASTJSON/documentation_legacy.json +++ b/test/libsolidity/ASTJSON/documentation_legacy.json @@ -114,6 +114,7 @@ null ], "name" : "fn", + "overrides" : null, "scope" : 15, "stateMutability" : "nonpayable", "superFunction" : null, diff --git a/test/libsolidity/ASTJSON/fallback.json b/test/libsolidity/ASTJSON/fallback.json index a9c85b2fb8b5..6374051d498a 100644 --- a/test/libsolidity/ASTJSON/fallback.json +++ b/test/libsolidity/ASTJSON/fallback.json @@ -41,6 +41,7 @@ "modifiers" : [], "name" : "", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 1, diff --git a/test/libsolidity/ASTJSON/fallback.sol b/test/libsolidity/ASTJSON/fallback.sol index 4e318892e327..7d346042d8a0 100644 --- a/test/libsolidity/ASTJSON/fallback.sol +++ b/test/libsolidity/ASTJSON/fallback.sol @@ -2,3 +2,5 @@ contract C { function() external payable { } } + +// ---- diff --git a/test/libsolidity/ASTJSON/fallback_legacy.json b/test/libsolidity/ASTJSON/fallback_legacy.json index 0aca3128e17e..4e31a33ea770 100644 --- a/test/libsolidity/ASTJSON/fallback_legacy.json +++ b/test/libsolidity/ASTJSON/fallback_legacy.json @@ -47,6 +47,7 @@ null ], "name" : "", + "overrides" : null, "scope" : 5, "stateMutability" : "payable", "superFunction" : null, diff --git a/test/libsolidity/ASTJSON/fallback_payable.json b/test/libsolidity/ASTJSON/fallback_payable.json index 9d56f74bdbce..49a7a33a904e 100644 --- a/test/libsolidity/ASTJSON/fallback_payable.json +++ b/test/libsolidity/ASTJSON/fallback_payable.json @@ -41,6 +41,7 @@ "modifiers" : [], "name" : "", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 1, diff --git a/test/libsolidity/ASTJSON/fallback_payable.sol b/test/libsolidity/ASTJSON/fallback_payable.sol index 21db99ecd71d..4a3cee6b5114 100644 --- a/test/libsolidity/ASTJSON/fallback_payable.sol +++ b/test/libsolidity/ASTJSON/fallback_payable.sol @@ -1,3 +1,5 @@ contract C { function() external {} } + +// ---- diff --git a/test/libsolidity/ASTJSON/fallback_payable_legacy.json b/test/libsolidity/ASTJSON/fallback_payable_legacy.json index 7320f574a3fe..af148555b4ec 100644 --- a/test/libsolidity/ASTJSON/fallback_payable_legacy.json +++ b/test/libsolidity/ASTJSON/fallback_payable_legacy.json @@ -47,6 +47,7 @@ null ], "name" : "", + "overrides" : null, "scope" : 5, "stateMutability" : "nonpayable", "superFunction" : null, diff --git a/test/libsolidity/ASTJSON/function_type.json b/test/libsolidity/ASTJSON/function_type.json index b78d844635c3..8e60d2ef160a 100644 --- a/test/libsolidity/ASTJSON/function_type.json +++ b/test/libsolidity/ASTJSON/function_type.json @@ -41,6 +41,7 @@ "modifiers" : [], "name" : "f", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 7, @@ -52,6 +53,7 @@ "id" : 6, "name" : "x", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 16, "src" : "24:44:1", "stateVariable" : false, @@ -83,6 +85,7 @@ "id" : 3, "name" : "", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 5, "src" : "61:4:1", "stateVariable" : false, @@ -136,6 +139,7 @@ "id" : 13, "name" : "", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 16, "src" : "79:40:1", "stateVariable" : false, @@ -167,6 +171,7 @@ "id" : 10, "name" : "", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 12, "src" : "113:4:1", "stateVariable" : false, diff --git a/test/libsolidity/ASTJSON/function_type_legacy.json b/test/libsolidity/ASTJSON/function_type_legacy.json index 72ceec81e21a..90b5a8e4d701 100644 --- a/test/libsolidity/ASTJSON/function_type_legacy.json +++ b/test/libsolidity/ASTJSON/function_type_legacy.json @@ -47,6 +47,7 @@ null ], "name" : "f", + "overrides" : null, "scope" : 17, "stateMutability" : "nonpayable", "superFunction" : null, @@ -62,6 +63,7 @@ { "constant" : false, "name" : "x", + "overrides" : null, "scope" : 16, "stateVariable" : false, "storageLocation" : "default", @@ -101,6 +103,7 @@ { "constant" : false, "name" : "", + "overrides" : null, "scope" : 5, "stateVariable" : false, "storageLocation" : "default", @@ -153,6 +156,7 @@ { "constant" : false, "name" : "", + "overrides" : null, "scope" : 16, "stateVariable" : false, "storageLocation" : "default", @@ -192,6 +196,7 @@ { "constant" : false, "name" : "", + "overrides" : null, "scope" : 12, "stateVariable" : false, "storageLocation" : "default", diff --git a/test/libsolidity/ASTJSON/long_type_name_binary_operation.json b/test/libsolidity/ASTJSON/long_type_name_binary_operation.json index c6d40af24f59..acc60daf0604 100644 --- a/test/libsolidity/ASTJSON/long_type_name_binary_operation.json +++ b/test/libsolidity/ASTJSON/long_type_name_binary_operation.json @@ -46,6 +46,7 @@ "id" : 4, "name" : "a", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 9, "src" : "35:6:1", "stateVariable" : false, @@ -146,6 +147,7 @@ "modifiers" : [], "name" : "f", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 1, diff --git a/test/libsolidity/ASTJSON/long_type_name_binary_operation.sol b/test/libsolidity/ASTJSON/long_type_name_binary_operation.sol index f07029d7a76d..745b14ae8b22 100644 --- a/test/libsolidity/ASTJSON/long_type_name_binary_operation.sol +++ b/test/libsolidity/ASTJSON/long_type_name_binary_operation.sol @@ -1 +1,3 @@ contract c { function f() public { uint a = 2 + 3; } } + +// ---- diff --git a/test/libsolidity/ASTJSON/long_type_name_binary_operation_legacy.json b/test/libsolidity/ASTJSON/long_type_name_binary_operation_legacy.json index b53332860ea5..cccf82f6dce5 100644 --- a/test/libsolidity/ASTJSON/long_type_name_binary_operation_legacy.json +++ b/test/libsolidity/ASTJSON/long_type_name_binary_operation_legacy.json @@ -47,6 +47,7 @@ null ], "name" : "f", + "overrides" : null, "scope" : 11, "stateMutability" : "nonpayable", "superFunction" : null, @@ -98,6 +99,7 @@ { "constant" : false, "name" : "a", + "overrides" : null, "scope" : 9, "stateVariable" : false, "storageLocation" : "default", diff --git a/test/libsolidity/ASTJSON/long_type_name_identifier.json b/test/libsolidity/ASTJSON/long_type_name_identifier.json index 505d260c4141..dc0c6447f0d3 100644 --- a/test/libsolidity/ASTJSON/long_type_name_identifier.json +++ b/test/libsolidity/ASTJSON/long_type_name_identifier.json @@ -31,6 +31,7 @@ "id" : 3, "name" : "a", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 14, "src" : "13:8:1", "stateVariable" : true, @@ -87,6 +88,7 @@ "id" : 9, "name" : "b", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 12, "src" : "45:16:1", "stateVariable" : false, @@ -152,6 +154,7 @@ "modifiers" : [], "name" : "f", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 4, diff --git a/test/libsolidity/ASTJSON/long_type_name_identifier.sol b/test/libsolidity/ASTJSON/long_type_name_identifier.sol index f03f7a84d3b7..60193cebb0c8 100644 --- a/test/libsolidity/ASTJSON/long_type_name_identifier.sol +++ b/test/libsolidity/ASTJSON/long_type_name_identifier.sol @@ -1 +1,3 @@ contract c { uint[] a; function f() public { uint[] storage b = a; } } + +// ---- diff --git a/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json b/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json index d3bcda561a57..4576770890a0 100644 --- a/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json +++ b/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json @@ -40,6 +40,7 @@ { "constant" : false, "name" : "a", + "overrides" : null, "scope" : 14, "stateVariable" : true, "storageLocation" : "default", @@ -89,6 +90,7 @@ null ], "name" : "f", + "overrides" : null, "scope" : 14, "stateMutability" : "nonpayable", "superFunction" : null, @@ -140,6 +142,7 @@ { "constant" : false, "name" : "b", + "overrides" : null, "scope" : 12, "stateVariable" : false, "storageLocation" : "storage", diff --git a/test/libsolidity/ASTJSON/modifier_definition.json b/test/libsolidity/ASTJSON/modifier_definition.json index 66359453c3ee..0e512e8049dd 100644 --- a/test/libsolidity/ASTJSON/modifier_definition.json +++ b/test/libsolidity/ASTJSON/modifier_definition.json @@ -56,6 +56,7 @@ "id" : 2, "name" : "i", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 6, "src" : "24:6:1", "stateVariable" : false, @@ -145,6 +146,7 @@ ], "name" : "F", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 7, diff --git a/test/libsolidity/ASTJSON/modifier_definition.sol b/test/libsolidity/ASTJSON/modifier_definition.sol index 96474e0f35d1..1dcdb59468ca 100644 --- a/test/libsolidity/ASTJSON/modifier_definition.sol +++ b/test/libsolidity/ASTJSON/modifier_definition.sol @@ -1 +1,3 @@ contract C { modifier M(uint i) { _; } function F() M(1) public {} } + +// ---- diff --git a/test/libsolidity/ASTJSON/modifier_definition_legacy.json b/test/libsolidity/ASTJSON/modifier_definition_legacy.json index 5186912c87e4..5bb91624ebfe 100644 --- a/test/libsolidity/ASTJSON/modifier_definition_legacy.json +++ b/test/libsolidity/ASTJSON/modifier_definition_legacy.json @@ -52,6 +52,7 @@ { "constant" : false, "name" : "i", + "overrides" : null, "scope" : 6, "stateVariable" : false, "storageLocation" : "default", @@ -107,6 +108,7 @@ "isConstructor" : false, "kind" : "function", "name" : "F", + "overrides" : null, "scope" : 14, "stateMutability" : "nonpayable", "superFunction" : null, diff --git a/test/libsolidity/ASTJSON/modifier_invocation.json b/test/libsolidity/ASTJSON/modifier_invocation.json index 66359453c3ee..0e512e8049dd 100644 --- a/test/libsolidity/ASTJSON/modifier_invocation.json +++ b/test/libsolidity/ASTJSON/modifier_invocation.json @@ -56,6 +56,7 @@ "id" : 2, "name" : "i", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 6, "src" : "24:6:1", "stateVariable" : false, @@ -145,6 +146,7 @@ ], "name" : "F", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 7, diff --git a/test/libsolidity/ASTJSON/modifier_invocation.sol b/test/libsolidity/ASTJSON/modifier_invocation.sol index 96474e0f35d1..1dcdb59468ca 100644 --- a/test/libsolidity/ASTJSON/modifier_invocation.sol +++ b/test/libsolidity/ASTJSON/modifier_invocation.sol @@ -1 +1,3 @@ contract C { modifier M(uint i) { _; } function F() M(1) public {} } + +// ---- diff --git a/test/libsolidity/ASTJSON/modifier_invocation_legacy.json b/test/libsolidity/ASTJSON/modifier_invocation_legacy.json index 5186912c87e4..5bb91624ebfe 100644 --- a/test/libsolidity/ASTJSON/modifier_invocation_legacy.json +++ b/test/libsolidity/ASTJSON/modifier_invocation_legacy.json @@ -52,6 +52,7 @@ { "constant" : false, "name" : "i", + "overrides" : null, "scope" : 6, "stateVariable" : false, "storageLocation" : "default", @@ -107,6 +108,7 @@ "isConstructor" : false, "kind" : "function", "name" : "F", + "overrides" : null, "scope" : 14, "stateMutability" : "nonpayable", "superFunction" : null, diff --git a/test/libsolidity/ASTJSON/non_utf8.json b/test/libsolidity/ASTJSON/non_utf8.json index 1852bd38f892..99312bd46d12 100644 --- a/test/libsolidity/ASTJSON/non_utf8.json +++ b/test/libsolidity/ASTJSON/non_utf8.json @@ -46,6 +46,7 @@ "id" : 3, "name" : "x", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 6, "src" : "35:5:1", "stateVariable" : false, @@ -93,6 +94,7 @@ "modifiers" : [], "name" : "f", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 1, diff --git a/test/libsolidity/ASTJSON/non_utf8.sol b/test/libsolidity/ASTJSON/non_utf8.sol index b83f3d706e20..f9a79d2fa6de 100644 --- a/test/libsolidity/ASTJSON/non_utf8.sol +++ b/test/libsolidity/ASTJSON/non_utf8.sol @@ -1 +1,3 @@ contract C { function f() public { var x = hex"ff"; } } + +// ---- diff --git a/test/libsolidity/ASTJSON/non_utf8_legacy.json b/test/libsolidity/ASTJSON/non_utf8_legacy.json index df105096676d..5abbce9742d0 100644 --- a/test/libsolidity/ASTJSON/non_utf8_legacy.json +++ b/test/libsolidity/ASTJSON/non_utf8_legacy.json @@ -47,6 +47,7 @@ null ], "name" : "f", + "overrides" : null, "scope" : 8, "stateMutability" : "nonpayable", "superFunction" : null, @@ -98,6 +99,7 @@ { "constant" : false, "name" : "x", + "overrides" : null, "scope" : 6, "stateVariable" : false, "storageLocation" : "default", diff --git a/test/libsolidity/ASTJSON/override.json b/test/libsolidity/ASTJSON/override.json new file mode 100644 index 000000000000..976ae7c1db15 --- /dev/null +++ b/test/libsolidity/ASTJSON/override.json @@ -0,0 +1,337 @@ +{ + "absolutePath" : "a", + "exportedSymbols" : + { + "A" : + [ + 5 + ], + "B" : + [ + 16 + ], + "C" : + [ + 31 + ] + }, + "id" : 32, + "nodeType" : "SourceUnit", + "nodes" : + [ + { + "baseContracts" : [], + "contractDependencies" : [], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "id" : 5, + "linearizedBaseContracts" : + [ + 5 + ], + "name" : "A", + "nodeType" : "ContractDefinition", + "nodes" : + [ + { + "body" : + { + "id" : 3, + "nodeType" : "Block", + "src" : "36:2:1", + "statements" : [] + }, + "documentation" : null, + "id" : 4, + "implemented" : true, + "kind" : "function", + "modifiers" : [], + "name" : "faa", + "nodeType" : "FunctionDefinition", + "overrides" : null, + "parameters" : + { + "id" : 1, + "nodeType" : "ParameterList", + "parameters" : [], + "src" : "26:2:1" + }, + "returnParameters" : + { + "id" : 2, + "nodeType" : "ParameterList", + "parameters" : [], + "src" : "36:0:1" + }, + "scope" : 5, + "src" : "14:24:1", + "stateMutability" : "nonpayable", + "superFunction" : null, + "visibility" : "public" + } + ], + "scope" : 32, + "src" : "0:40:1" + }, + { + "baseContracts" : + [ + { + "arguments" : null, + "baseName" : + { + "contractScope" : null, + "id" : 6, + "name" : "A", + "nodeType" : "UserDefinedTypeName", + "referencedDeclaration" : 5, + "src" : "55:1:1", + "typeDescriptions" : + { + "typeIdentifier" : "t_contract$_A_$5", + "typeString" : "contract A" + } + }, + "id" : 7, + "nodeType" : "InheritanceSpecifier", + "src" : "55:1:1" + } + ], + "contractDependencies" : + [ + 5 + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : false, + "id" : 16, + "linearizedBaseContracts" : + [ + 16, + 5 + ], + "name" : "B", + "nodeType" : "ContractDefinition", + "nodes" : + [ + { + "body" : null, + "documentation" : null, + "id" : 10, + "implemented" : false, + "kind" : "function", + "modifiers" : [], + "name" : "foo", + "nodeType" : "FunctionDefinition", + "overrides" : null, + "parameters" : + { + "id" : 8, + "nodeType" : "ParameterList", + "parameters" : [], + "src" : "72:2:1" + }, + "returnParameters" : + { + "id" : 9, + "nodeType" : "ParameterList", + "parameters" : [], + "src" : "81:0:1" + }, + "scope" : 16, + "src" : "60:22:1", + "stateMutability" : "nonpayable", + "superFunction" : null, + "visibility" : "public" + }, + { + "body" : + { + "id" : 14, + "nodeType" : "Block", + "src" : "115:2:1", + "statements" : [] + }, + "documentation" : null, + "id" : 15, + "implemented" : true, + "kind" : "function", + "modifiers" : [], + "name" : "faa", + "nodeType" : "FunctionDefinition", + "overrides" : [], + "parameters" : + { + "id" : 11, + "nodeType" : "ParameterList", + "parameters" : [], + "src" : "96:2:1" + }, + "returnParameters" : + { + "id" : 13, + "nodeType" : "ParameterList", + "parameters" : [], + "src" : "115:0:1" + }, + "scope" : 16, + "src" : "84:33:1", + "stateMutability" : "nonpayable", + "superFunction" : 4, + "visibility" : "public" + } + ], + "scope" : 32, + "src" : "41:78:1" + }, + { + "baseContracts" : + [ + { + "arguments" : null, + "baseName" : + { + "contractScope" : null, + "id" : 17, + "name" : "B", + "nodeType" : "UserDefinedTypeName", + "referencedDeclaration" : 16, + "src" : "134:1:1", + "typeDescriptions" : + { + "typeIdentifier" : "t_contract$_B_$16", + "typeString" : "contract B" + } + }, + "id" : 18, + "nodeType" : "InheritanceSpecifier", + "src" : "134:1:1" + } + ], + "contractDependencies" : + [ + 5, + 16 + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "id" : 31, + "linearizedBaseContracts" : + [ + 31, + 16, + 5 + ], + "name" : "C", + "nodeType" : "ContractDefinition", + "nodes" : + [ + { + "body" : + { + "id" : 22, + "nodeType" : "Block", + "src" : "170:3:1", + "statements" : [] + }, + "documentation" : null, + "id" : 23, + "implemented" : true, + "kind" : "function", + "modifiers" : [], + "name" : "foo", + "nodeType" : "FunctionDefinition", + "overrides" : [], + "parameters" : + { + "id" : 19, + "nodeType" : "ParameterList", + "parameters" : [], + "src" : "151:2:1" + }, + "returnParameters" : + { + "id" : 21, + "nodeType" : "ParameterList", + "parameters" : [], + "src" : "170:0:1" + }, + "scope" : 31, + "src" : "139:34:1", + "stateMutability" : "nonpayable", + "superFunction" : 10, + "visibility" : "public" + }, + { + "body" : + { + "id" : 29, + "nodeType" : "Block", + "src" : "212:2:1", + "statements" : [] + }, + "documentation" : null, + "id" : 30, + "implemented" : true, + "kind" : "function", + "modifiers" : [], + "name" : "faa", + "nodeType" : "FunctionDefinition", + "overrides" : + [ + { + "contractScope" : null, + "id" : 25, + "name" : "A", + "nodeType" : "UserDefinedTypeName", + "referencedDeclaration" : 5, + "src" : "206:1:1", + "typeDescriptions" : + { + "typeIdentifier" : "t_contract$_A_$5", + "typeString" : "contract A" + } + }, + { + "contractScope" : null, + "id" : 26, + "name" : "B", + "nodeType" : "UserDefinedTypeName", + "referencedDeclaration" : 16, + "src" : "209:1:1", + "typeDescriptions" : + { + "typeIdentifier" : "t_contract$_B_$16", + "typeString" : "contract B" + } + } + ], + "parameters" : + { + "id" : 24, + "nodeType" : "ParameterList", + "parameters" : [], + "src" : "187:2:1" + }, + "returnParameters" : + { + "id" : 28, + "nodeType" : "ParameterList", + "parameters" : [], + "src" : "212:0:1" + }, + "scope" : 31, + "src" : "175:39:1", + "stateMutability" : "nonpayable", + "superFunction" : 15, + "visibility" : "public" + } + ], + "scope" : 32, + "src" : "120:96:1" + } + ], + "src" : "0:217:1" +} diff --git a/test/libsolidity/ASTJSON/override.sol b/test/libsolidity/ASTJSON/override.sol new file mode 100644 index 000000000000..3edb20df05d2 --- /dev/null +++ b/test/libsolidity/ASTJSON/override.sol @@ -0,0 +1,13 @@ +contract A { + function faa() public {} +} +contract B is A { + function foo() public; + function faa() public override {} +} +contract C is B { + function foo() public override { } + function faa() public override(A, B) {} +} + +// ---- diff --git a/test/libsolidity/ASTJSON/override_legacy.json b/test/libsolidity/ASTJSON/override_legacy.json new file mode 100644 index 000000000000..d7ef04356584 --- /dev/null +++ b/test/libsolidity/ASTJSON/override_legacy.json @@ -0,0 +1,492 @@ +{ + "attributes" : + { + "absolutePath" : "a", + "exportedSymbols" : + { + "A" : + [ + 5 + ], + "B" : + [ + 16 + ], + "C" : + [ + 31 + ] + } + }, + "children" : + [ + { + "attributes" : + { + "baseContracts" : + [ + null + ], + "contractDependencies" : + [ + null + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "linearizedBaseContracts" : + [ + 5 + ], + "name" : "A", + "scope" : 32 + }, + "children" : + [ + { + "attributes" : + { + "documentation" : null, + "implemented" : true, + "isConstructor" : false, + "kind" : "function", + "modifiers" : + [ + null + ], + "name" : "faa", + "overrides" : null, + "scope" : 5, + "stateMutability" : "nonpayable", + "superFunction" : null, + "visibility" : "public" + }, + "children" : + [ + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 1, + "name" : "ParameterList", + "src" : "26:2:1" + }, + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 2, + "name" : "ParameterList", + "src" : "36:0:1" + }, + { + "attributes" : + { + "statements" : + [ + null + ] + }, + "children" : [], + "id" : 3, + "name" : "Block", + "src" : "36:2:1" + } + ], + "id" : 4, + "name" : "FunctionDefinition", + "src" : "14:24:1" + } + ], + "id" : 5, + "name" : "ContractDefinition", + "src" : "0:40:1" + }, + { + "attributes" : + { + "contractDependencies" : + [ + 5 + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : false, + "linearizedBaseContracts" : + [ + 16, + 5 + ], + "name" : "B", + "scope" : 32 + }, + "children" : + [ + { + "attributes" : + { + "arguments" : null + }, + "children" : + [ + { + "attributes" : + { + "contractScope" : null, + "name" : "A", + "referencedDeclaration" : 5, + "type" : "contract A" + }, + "id" : 6, + "name" : "UserDefinedTypeName", + "src" : "55:1:1" + } + ], + "id" : 7, + "name" : "InheritanceSpecifier", + "src" : "55:1:1" + }, + { + "attributes" : + { + "body" : null, + "documentation" : null, + "implemented" : false, + "isConstructor" : false, + "kind" : "function", + "modifiers" : + [ + null + ], + "name" : "foo", + "overrides" : null, + "scope" : 16, + "stateMutability" : "nonpayable", + "superFunction" : null, + "visibility" : "public" + }, + "children" : + [ + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 8, + "name" : "ParameterList", + "src" : "72:2:1" + }, + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 9, + "name" : "ParameterList", + "src" : "81:0:1" + } + ], + "id" : 10, + "name" : "FunctionDefinition", + "src" : "60:22:1" + }, + { + "attributes" : + { + "documentation" : null, + "implemented" : true, + "isConstructor" : false, + "kind" : "function", + "modifiers" : + [ + null + ], + "name" : "faa", + "overrides" : + [ + null + ], + "scope" : 16, + "stateMutability" : "nonpayable", + "superFunction" : 4, + "visibility" : "public" + }, + "children" : + [ + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 11, + "name" : "ParameterList", + "src" : "96:2:1" + }, + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 13, + "name" : "ParameterList", + "src" : "115:0:1" + }, + { + "attributes" : + { + "statements" : + [ + null + ] + }, + "children" : [], + "id" : 14, + "name" : "Block", + "src" : "115:2:1" + } + ], + "id" : 15, + "name" : "FunctionDefinition", + "src" : "84:33:1" + } + ], + "id" : 16, + "name" : "ContractDefinition", + "src" : "41:78:1" + }, + { + "attributes" : + { + "contractDependencies" : + [ + 5, + 16 + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "linearizedBaseContracts" : + [ + 31, + 16, + 5 + ], + "name" : "C", + "scope" : 32 + }, + "children" : + [ + { + "attributes" : + { + "arguments" : null + }, + "children" : + [ + { + "attributes" : + { + "contractScope" : null, + "name" : "B", + "referencedDeclaration" : 16, + "type" : "contract B" + }, + "id" : 17, + "name" : "UserDefinedTypeName", + "src" : "134:1:1" + } + ], + "id" : 18, + "name" : "InheritanceSpecifier", + "src" : "134:1:1" + }, + { + "attributes" : + { + "documentation" : null, + "implemented" : true, + "isConstructor" : false, + "kind" : "function", + "modifiers" : + [ + null + ], + "name" : "foo", + "overrides" : + [ + null + ], + "scope" : 31, + "stateMutability" : "nonpayable", + "superFunction" : 10, + "visibility" : "public" + }, + "children" : + [ + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 19, + "name" : "ParameterList", + "src" : "151:2:1" + }, + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 21, + "name" : "ParameterList", + "src" : "170:0:1" + }, + { + "attributes" : + { + "statements" : + [ + null + ] + }, + "children" : [], + "id" : 22, + "name" : "Block", + "src" : "170:3:1" + } + ], + "id" : 23, + "name" : "FunctionDefinition", + "src" : "139:34:1" + }, + { + "attributes" : + { + "documentation" : null, + "implemented" : true, + "isConstructor" : false, + "kind" : "function", + "modifiers" : + [ + null + ], + "name" : "faa", + "scope" : 31, + "stateMutability" : "nonpayable", + "superFunction" : 15, + "visibility" : "public" + }, + "children" : + [ + { + "attributes" : + { + "contractScope" : null, + "name" : "A", + "referencedDeclaration" : 5, + "type" : "contract A" + }, + "id" : 25, + "name" : "UserDefinedTypeName", + "src" : "206:1:1" + }, + { + "attributes" : + { + "contractScope" : null, + "name" : "B", + "referencedDeclaration" : 16, + "type" : "contract B" + }, + "id" : 26, + "name" : "UserDefinedTypeName", + "src" : "209:1:1" + }, + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 24, + "name" : "ParameterList", + "src" : "187:2:1" + }, + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 28, + "name" : "ParameterList", + "src" : "212:0:1" + }, + { + "attributes" : + { + "statements" : + [ + null + ] + }, + "children" : [], + "id" : 29, + "name" : "Block", + "src" : "212:2:1" + } + ], + "id" : 30, + "name" : "FunctionDefinition", + "src" : "175:39:1" + } + ], + "id" : 31, + "name" : "ContractDefinition", + "src" : "120:96:1" + } + ], + "id" : 32, + "name" : "SourceUnit", + "src" : "0:217:1" +} diff --git a/test/libsolidity/ASTJSON/short_type_name.json b/test/libsolidity/ASTJSON/short_type_name.json index acb46157108d..823d04d3df56 100644 --- a/test/libsolidity/ASTJSON/short_type_name.json +++ b/test/libsolidity/ASTJSON/short_type_name.json @@ -46,6 +46,7 @@ "id" : 6, "name" : "x", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 8, "src" : "35:15:1", "stateVariable" : false, @@ -97,6 +98,7 @@ "modifiers" : [], "name" : "f", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 1, diff --git a/test/libsolidity/ASTJSON/short_type_name.sol b/test/libsolidity/ASTJSON/short_type_name.sol index 533874ae44b5..077e715b9c60 100644 --- a/test/libsolidity/ASTJSON/short_type_name.sol +++ b/test/libsolidity/ASTJSON/short_type_name.sol @@ -1 +1,3 @@ contract c { function f() public { uint[] memory x; } } + +// ---- diff --git a/test/libsolidity/ASTJSON/short_type_name_legacy.json b/test/libsolidity/ASTJSON/short_type_name_legacy.json index 1f9b19687c25..ee4d1fce3ece 100644 --- a/test/libsolidity/ASTJSON/short_type_name_legacy.json +++ b/test/libsolidity/ASTJSON/short_type_name_legacy.json @@ -47,6 +47,7 @@ null ], "name" : "f", + "overrides" : null, "scope" : 10, "stateMutability" : "nonpayable", "superFunction" : null, @@ -99,6 +100,7 @@ { "constant" : false, "name" : "x", + "overrides" : null, "scope" : 8, "stateVariable" : false, "storageLocation" : "memory", diff --git a/test/libsolidity/ASTJSON/short_type_name_ref.json b/test/libsolidity/ASTJSON/short_type_name_ref.json index b6b7bca5d478..5224f26f2fee 100644 --- a/test/libsolidity/ASTJSON/short_type_name_ref.json +++ b/test/libsolidity/ASTJSON/short_type_name_ref.json @@ -46,6 +46,7 @@ "id" : 7, "name" : "rows", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 9, "src" : "35:20:1", "stateVariable" : false, @@ -109,6 +110,7 @@ "modifiers" : [], "name" : "f", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 1, diff --git a/test/libsolidity/ASTJSON/short_type_name_ref.sol b/test/libsolidity/ASTJSON/short_type_name_ref.sol index a808b982b486..9128d69d6975 100644 --- a/test/libsolidity/ASTJSON/short_type_name_ref.sol +++ b/test/libsolidity/ASTJSON/short_type_name_ref.sol @@ -1 +1,3 @@ contract c { function f() public { uint[][] memory rows; } } + +// ---- diff --git a/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json b/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json index 420b0f6095b3..0fbecedf8983 100644 --- a/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json +++ b/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json @@ -47,6 +47,7 @@ null ], "name" : "f", + "overrides" : null, "scope" : 11, "stateMutability" : "nonpayable", "superFunction" : null, @@ -99,6 +100,7 @@ { "constant" : false, "name" : "rows", + "overrides" : null, "scope" : 9, "stateVariable" : false, "storageLocation" : "memory", diff --git a/test/libsolidity/ASTJSON/source_location.json b/test/libsolidity/ASTJSON/source_location.json index f0ed216dbd9c..0a3c9ccd6d46 100644 --- a/test/libsolidity/ASTJSON/source_location.json +++ b/test/libsolidity/ASTJSON/source_location.json @@ -46,6 +46,7 @@ "id" : 3, "name" : "x", "nodeType" : "VariableDeclaration", + "overrides" : null, "scope" : 9, "src" : "28:5:1", "stateVariable" : false, @@ -131,6 +132,7 @@ "modifiers" : [], "name" : "f", "nodeType" : "FunctionDefinition", + "overrides" : null, "parameters" : { "id" : 1, diff --git a/test/libsolidity/ASTJSON/source_location.sol b/test/libsolidity/ASTJSON/source_location.sol index 1fcec2e665b8..1b763646dc45 100644 --- a/test/libsolidity/ASTJSON/source_location.sol +++ b/test/libsolidity/ASTJSON/source_location.sol @@ -1 +1,3 @@ contract C { function f() { var x = 2; x++; } } + +// ---- diff --git a/test/libsolidity/ASTJSON/source_location_legacy.json b/test/libsolidity/ASTJSON/source_location_legacy.json index a65979d66413..3c56e55f4a78 100644 --- a/test/libsolidity/ASTJSON/source_location_legacy.json +++ b/test/libsolidity/ASTJSON/source_location_legacy.json @@ -47,6 +47,7 @@ null ], "name" : "f", + "overrides" : null, "scope" : 11, "stateMutability" : "nonpayable", "superFunction" : null, @@ -98,6 +99,7 @@ { "constant" : false, "name" : "x", + "overrides" : null, "scope" : 9, "stateVariable" : false, "storageLocation" : "default", diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index 48ac00613adc..0979ce6b9213 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -545,7 +545,6 @@ BOOST_AUTO_TEST_CASE(keyword_is_reserved) "mutable", "null", "of", - "override", "partial", "promise", "reference", diff --git a/test/libsolidity/syntaxTests/inheritance/override/detect_double_override.sol b/test/libsolidity/syntaxTests/inheritance/override/detect_double_override.sol new file mode 100644 index 000000000000..60138f48dbcb --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/override/detect_double_override.sol @@ -0,0 +1,7 @@ +contract X { + int public override override testvar; + function test() internal override override returns (uint256); +} +// ---- +// ParserError: (34-42): Override already specified. +// ParserError: (87-95): Override already specified. diff --git a/test/libsolidity/syntaxTests/inheritance/override/override.sol b/test/libsolidity/syntaxTests/inheritance/override/override.sol new file mode 100644 index 000000000000..bb7aa7347efb --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/override/override.sol @@ -0,0 +1,5 @@ +contract X { + int public override testvar; + function test() internal override returns (uint256); +} +// ---- diff --git a/test/libsolidity/syntaxTests/inheritance/override/override_empty_list.sol b/test/libsolidity/syntaxTests/inheritance/override/override_empty_list.sol new file mode 100644 index 000000000000..2db86a1afe13 --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/override/override_empty_list.sol @@ -0,0 +1,10 @@ +contract A { + int public testvar; + function test() internal returns (uint256); +} +contract X is A { + int public override testvar; + function test() internal override() returns (uint256); +} +// ---- +// ParserError: (164-165): Expected identifier but got ')' diff --git a/test/libsolidity/syntaxTests/inheritance/override/override_multiple.sol b/test/libsolidity/syntaxTests/inheritance/override/override_multiple.sol new file mode 100644 index 000000000000..0b16056a669f --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/override/override_multiple.sol @@ -0,0 +1,9 @@ +contract A { + function foo() internal returns (uint256); +} +contract X { + int public override testvar; + function test() internal override returns (uint256); + function foo() internal override(X, A) returns (uint256); +} +// ---- diff --git a/test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail1.sol b/test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail1.sol new file mode 100644 index 000000000000..ebbf83e1644d --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail1.sol @@ -0,0 +1,8 @@ +contract A { + function foo() internal returns (uint256); +} +contract X { + int public override(A,) testvar; +} +// ---- +// ParserError: (95-96): Expected identifier but got ')' diff --git a/test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail2.sol b/test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail2.sol new file mode 100644 index 000000000000..2c3319ac22a5 --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail2.sol @@ -0,0 +1,8 @@ +contract A { + function foo() internal returns (uint256); +} +contract X { + function test() internal override(,) returns (uint256); +} +// ---- +// ParserError: (107-108): Expected identifier but got ',' diff --git a/test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail3.sol b/test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail3.sol new file mode 100644 index 000000000000..79ab20d8ba70 --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail3.sol @@ -0,0 +1,8 @@ +contract A { + function foo() internal returns (uint256); +} +contract X { + function foo() internal override(X, address) returns (uint256); +} +// ---- +// ParserError: (109-116): Expected identifier but got 'address' diff --git a/test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail4.sol b/test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail4.sol new file mode 100644 index 000000000000..d97fb27d6cf8 --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/override/override_multiple_fail4.sol @@ -0,0 +1,8 @@ +contract A { + function foo() internal returns (uint256); +} +contract X { + int public override() testvar; +} +// ---- +// ParserError: (93-94): Expected identifier but got ')' From 872d21f527f559539f29047ce9249558dfd0e2f6 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 15 Aug 2019 15:35:57 +0200 Subject: [PATCH 008/283] Allow global struct definitions. --- libsolidity/interface/CompilerStack.cpp | 8 ++++---- libsolidity/parsing/Parser.cpp | 5 ++++- test/libsolidity/semanticTests/structs/global.sol | 10 ++++++++++ .../structs/contract_global_struct_name_clash.sol | 4 ++++ test/libsolidity/syntaxTests/structs/global_struct.sol | 7 +++++++ .../structs/global_struct_contract_name_clash.sol | 4 ++++ .../syntaxTests/structs/global_struct_shadowing.sol | 10 ++++++++++ .../syntaxTests/structs/global_structs_name_clash.sol | 4 ++++ 8 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 test/libsolidity/semanticTests/structs/global.sol create mode 100644 test/libsolidity/syntaxTests/structs/contract_global_struct_name_clash.sol create mode 100644 test/libsolidity/syntaxTests/structs/global_struct.sol create mode 100644 test/libsolidity/syntaxTests/structs/global_struct_contract_name_clash.sol create mode 100644 test/libsolidity/syntaxTests/structs/global_struct_shadowing.sol create mode 100644 test/libsolidity/syntaxTests/structs/global_structs_name_clash.sol diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 7df52ca2364a..f3c8ffa15b1e 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -285,17 +285,17 @@ bool CompilerStack::analyze() // the special variables "this" and "super" must be set appropriately. for (Source const* source: m_sourceOrder) for (ASTPointer const& node: source->ast->nodes()) + { + if (!resolver.resolveNamesAndTypes(*node)) + return false; if (ContractDefinition* contract = dynamic_cast(node.get())) - { - - if (!resolver.resolveNamesAndTypes(*contract)) return false; // Note that we now reference contracts by their fully qualified names, and // thus contracts can only conflict if declared in the same source file. This // already causes a double-declaration error elsewhere, so we do not report // an error here and instead silently drop any additional contracts we find. if (m_contracts.find(contract->fullyQualifiedName()) == m_contracts.end()) m_contracts[contract->fullyQualifiedName()].contract = contract; - } + } // Next, we check inheritance, overrides, function collisions and other things at // contract or function level. diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index b358e4a9478d..7c42248f3817 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -96,8 +96,11 @@ ASTPointer Parser::parse(shared_ptr const& _scanner) case Token::Library: nodes.push_back(parseContractDefinition()); break; + case Token::Struct: + nodes.push_back(parseStructDefinition()); + break; default: - fatalParserError(string("Expected pragma, import directive or contract/interface/library definition.")); + fatalParserError(string("Expected pragma, import directive or contract/interface/library/struct definition.")); } } solAssert(m_recursionDepth == 0, ""); diff --git a/test/libsolidity/semanticTests/structs/global.sol b/test/libsolidity/semanticTests/structs/global.sol new file mode 100644 index 000000000000..18dbf87dd3c6 --- /dev/null +++ b/test/libsolidity/semanticTests/structs/global.sol @@ -0,0 +1,10 @@ +pragma experimental ABIEncoderV2; + +struct S { uint256 a; uint256 b; } +contract C { + function f(S calldata s) external pure returns (uint256, uint256) { + return (s.a, s.b); + } +} +// ---- +// f((uint256,uint256)): 42, 23 -> 42, 23 diff --git a/test/libsolidity/syntaxTests/structs/contract_global_struct_name_clash.sol b/test/libsolidity/syntaxTests/structs/contract_global_struct_name_clash.sol new file mode 100644 index 000000000000..d8476f116ce9 --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/contract_global_struct_name_clash.sol @@ -0,0 +1,4 @@ +contract S {} +struct S { uint256 a; } +// ---- +// DeclarationError: (14-37): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/structs/global_struct.sol b/test/libsolidity/syntaxTests/structs/global_struct.sol new file mode 100644 index 000000000000..219467eac6e1 --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/global_struct.sol @@ -0,0 +1,7 @@ +struct S { uint a; } +contract C { + function f() public pure { + S memory s = S(42); + s; + } +} \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/structs/global_struct_contract_name_clash.sol b/test/libsolidity/syntaxTests/structs/global_struct_contract_name_clash.sol new file mode 100644 index 000000000000..84ff22872e95 --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/global_struct_contract_name_clash.sol @@ -0,0 +1,4 @@ +struct S { uint256 a; } +contract S {} +// ---- +// DeclarationError: (24-37): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/structs/global_struct_shadowing.sol b/test/libsolidity/syntaxTests/structs/global_struct_shadowing.sol new file mode 100644 index 000000000000..1a3e58443b62 --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/global_struct_shadowing.sol @@ -0,0 +1,10 @@ +struct S { uint a; } +contract C { + struct S { address x; } + function f() public view { + S memory s = S(address(this)); + s; + } +} +// ---- +// Warning: (38-61): This declaration shadows an existing declaration. diff --git a/test/libsolidity/syntaxTests/structs/global_structs_name_clash.sol b/test/libsolidity/syntaxTests/structs/global_structs_name_clash.sol new file mode 100644 index 000000000000..ce17f4c817b5 --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/global_structs_name_clash.sol @@ -0,0 +1,4 @@ +struct S { uint256 a; } +struct S { uint256 a; } +// ---- +// DeclarationError: (24-47): Identifier already declared. From fae0e10d26842f4ac93319a7ca07b482cfc49b30 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 2 Sep 2019 11:17:57 +0200 Subject: [PATCH 009/283] Import tests. --- .../imports/name_clash_in_import_contract_struct_1.sol | 7 +++++++ .../imports/name_clash_in_import_contract_struct_2.sol | 7 +++++++ .../imports/name_clash_in_import_contract_struct_3.sol | 7 +++++++ .../imports/name_clash_in_import_contract_struct_4.sol | 7 +++++++ .../imports/name_clash_in_import_contract_struct_5.sol | 5 +++++ .../syntaxTests/imports/name_clash_in_import_struct_1.sol | 7 +++++++ .../syntaxTests/imports/name_clash_in_import_struct_2.sol | 7 +++++++ .../syntaxTests/imports/name_clash_in_import_struct_3.sol | 7 +++++++ .../syntaxTests/imports/name_clash_in_import_struct_4.sol | 7 +++++++ .../syntaxTests/imports/name_clash_in_import_struct_5.sol | 5 +++++ .../imports/name_clash_in_import_struct_contract_1.sol | 7 +++++++ .../imports/name_clash_in_import_struct_contract_2.sol | 7 +++++++ .../imports/name_clash_in_import_struct_contract_3.sol | 7 +++++++ .../imports/name_clash_in_import_struct_contract_4.sol | 7 +++++++ .../imports/name_clash_in_import_struct_contract_5.sol | 5 +++++ 15 files changed, 99 insertions(+) create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_1.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_2.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_3.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_4.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_5.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_1.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_2.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_3.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_4.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_5.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_1.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_2.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_3.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_4.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_5.sol diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_1.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_1.sol new file mode 100644 index 000000000000..83256e0ba82a --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_1.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +contract A {} +==== Source: b ==== +import "a"; +struct A { uint256 a; } +// ---- +// DeclarationError: (b:12-35): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_2.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_2.sol new file mode 100644 index 000000000000..20179bfc44c2 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_2.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +contract A {} +==== Source: b ==== +import "a" as A; +struct A { uint256 a; } +// ---- +// DeclarationError: (b:17-40): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_3.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_3.sol new file mode 100644 index 000000000000..23958ad367e7 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_3.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +contract A {} +==== Source: b ==== +import {A as b} from "a"; +struct b { uint256 a; } +// ---- +// DeclarationError: (b:26-49): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_4.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_4.sol new file mode 100644 index 000000000000..1c5258042494 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_4.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +contract A {} +==== Source: b ==== +import {A} from "a"; +struct A { uint256 a; } +// ---- +// DeclarationError: (b:21-44): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_5.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_5.sol new file mode 100644 index 000000000000..43ade32a43c5 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_contract_struct_5.sol @@ -0,0 +1,5 @@ +==== Source: a ==== +contract A {} +==== Source: b ==== +import {A} from "a"; +struct B { uint256 a; } diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_1.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_1.sol new file mode 100644 index 000000000000..f754ce28f3e8 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_1.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +struct A { uint256 a; } +==== Source: b ==== +import "a"; +struct A { uint256 a; } +// ---- +// DeclarationError: (b:12-35): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_2.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_2.sol new file mode 100644 index 000000000000..9b1de8e6b879 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_2.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +struct A { uint256 a; } +==== Source: b ==== +import "a" as A; +struct A { uint256 a; } +// ---- +// DeclarationError: (b:17-40): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_3.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_3.sol new file mode 100644 index 000000000000..1a7d662747a6 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_3.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +struct A { uint256 a; } +==== Source: b ==== +import {A as b} from "a"; +struct b { uint256 a; } +// ---- +// DeclarationError: (b:26-49): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_4.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_4.sol new file mode 100644 index 000000000000..f146ca6547e1 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_4.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +struct A { uint256 a; } +==== Source: b ==== +import {A} from "a"; +struct A { uint256 a; } +// ---- +// DeclarationError: (b:21-44): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_5.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_5.sol new file mode 100644 index 000000000000..0d1759e4ad1b --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_5.sol @@ -0,0 +1,5 @@ +==== Source: a ==== +struct A { uint256 a; } +==== Source: b ==== +import {A} from "a"; +struct B { uint256 a; } diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_1.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_1.sol new file mode 100644 index 000000000000..21c0efd70fb4 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_1.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +struct A { uint256 a; } +==== Source: b ==== +import "a"; +contract A {} +// ---- +// DeclarationError: (b:12-25): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_2.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_2.sol new file mode 100644 index 000000000000..c248d27430cb --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_2.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +struct A { uint256 a; } +==== Source: b ==== +import "a" as A; +contract A {} +// ---- +// DeclarationError: (b:17-30): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_3.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_3.sol new file mode 100644 index 000000000000..aec99ced8261 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_3.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +struct A { uint256 a; } +==== Source: b ==== +import {A as b} from "a"; +contract b {} +// ---- +// DeclarationError: (b:26-39): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_4.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_4.sol new file mode 100644 index 000000000000..292bd7529f5e --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_4.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +struct A { uint256 a; } +==== Source: b ==== +import {A} from "a"; +contract A {} +// ---- +// DeclarationError: (b:21-34): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_5.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_5.sol new file mode 100644 index 000000000000..18f03158de2f --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_struct_contract_5.sol @@ -0,0 +1,5 @@ +==== Source: a ==== +struct A { uint256 a; } +==== Source: b ==== +import {A} from "a"; +contract B {} From 2b938d703c75594b109bcf48e15cca94ad109f60 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 2 Sep 2019 11:52:51 +0200 Subject: [PATCH 010/283] Allow global enum definitions. --- libsolidity/parsing/Parser.cpp | 5 ++++- test/libsolidity/syntaxTests/enums/global_enum.sol | 7 +++++++ .../enums/global_enum_contract_name_clash.sol | 4 ++++ .../syntaxTests/enums/global_enum_name_clash.sol | 4 ++++ .../syntaxTests/enums/global_enum_shadowing.sol | 10 ++++++++++ .../syntaxTests/imports/name_clash_in_import_enum.sol | 7 +++++++ .../imports/name_clash_in_import_enum_contract.sol | 7 +++++++ .../imports/name_clash_in_import_enum_struct.sol | 7 +++++++ 8 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/syntaxTests/enums/global_enum.sol create mode 100644 test/libsolidity/syntaxTests/enums/global_enum_contract_name_clash.sol create mode 100644 test/libsolidity/syntaxTests/enums/global_enum_name_clash.sol create mode 100644 test/libsolidity/syntaxTests/enums/global_enum_shadowing.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_enum.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_enum_contract.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_enum_struct.sol diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 7c42248f3817..1945a07dcdc8 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -99,8 +99,11 @@ ASTPointer Parser::parse(shared_ptr const& _scanner) case Token::Struct: nodes.push_back(parseStructDefinition()); break; + case Token::Enum: + nodes.push_back(parseEnumDefinition()); + break; default: - fatalParserError(string("Expected pragma, import directive or contract/interface/library/struct definition.")); + fatalParserError(string("Expected pragma, import directive or contract/interface/library/struct/enum definition.")); } } solAssert(m_recursionDepth == 0, ""); diff --git a/test/libsolidity/syntaxTests/enums/global_enum.sol b/test/libsolidity/syntaxTests/enums/global_enum.sol new file mode 100644 index 000000000000..1229b22c2659 --- /dev/null +++ b/test/libsolidity/syntaxTests/enums/global_enum.sol @@ -0,0 +1,7 @@ +enum E { A } +contract C { + function f() public pure { + E e = E.A; + e; + } +} \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/enums/global_enum_contract_name_clash.sol b/test/libsolidity/syntaxTests/enums/global_enum_contract_name_clash.sol new file mode 100644 index 000000000000..be667496f0eb --- /dev/null +++ b/test/libsolidity/syntaxTests/enums/global_enum_contract_name_clash.sol @@ -0,0 +1,4 @@ +enum E { A } +contract E {} +// ---- +// DeclarationError: (13-26): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/enums/global_enum_name_clash.sol b/test/libsolidity/syntaxTests/enums/global_enum_name_clash.sol new file mode 100644 index 000000000000..dd49c33adab2 --- /dev/null +++ b/test/libsolidity/syntaxTests/enums/global_enum_name_clash.sol @@ -0,0 +1,4 @@ +enum E { A } +enum E { A } +// ---- +// DeclarationError: (13-25): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/enums/global_enum_shadowing.sol b/test/libsolidity/syntaxTests/enums/global_enum_shadowing.sol new file mode 100644 index 000000000000..240d7f6488f4 --- /dev/null +++ b/test/libsolidity/syntaxTests/enums/global_enum_shadowing.sol @@ -0,0 +1,10 @@ +enum E { A } +contract C { + enum E { A } + function f() public pure { + E e = E.A; + e; + } +} +// ---- +// Warning: (30-42): This declaration shadows an existing declaration. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_enum.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_enum.sol new file mode 100644 index 000000000000..f3e583dfff15 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_enum.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +enum E { A } +==== Source: b ==== +import "a"; +enum E { A } +// ---- +// DeclarationError: (b:12-24): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_enum_contract.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_enum_contract.sol new file mode 100644 index 000000000000..31e56bab4522 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_enum_contract.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +enum E { A } +==== Source: b ==== +import "a"; +contract E { } +// ---- +// DeclarationError: (b:12-26): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_enum_struct.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_enum_struct.sol new file mode 100644 index 000000000000..3c204e3f05c2 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_enum_struct.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +enum E { A } +==== Source: b ==== +import "a"; +struct E { uint256 a; } +// ---- +// DeclarationError: (b:12-35): Identifier already declared. From c5eedc9e0b4e21559c292381b10eccd1d78b1df0 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 2 Sep 2019 12:01:09 +0200 Subject: [PATCH 011/283] Changelog entry. --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index aea8d4848641..58bef67f9ac0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Breaking changes: Language Features: + * Allow global enums and structs. Compiler Features: From 467d420f7e602ec721d630b59bcdab8b3eadfa7e Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Mon, 2 Sep 2019 12:23:21 +0200 Subject: [PATCH 012/283] ABI and AST tests. --- test/libsolidity/ABIJson/global_struct.sol | 58 +++++++++++++++++ test/libsolidity/ASTJSON/global_enum.json | 32 ++++++++++ test/libsolidity/ASTJSON/global_enum.sol | 3 + .../ASTJSON/global_enum_legacy.json | 41 ++++++++++++ test/libsolidity/ASTJSON/global_struct.json | 58 +++++++++++++++++ test/libsolidity/ASTJSON/global_struct.sol | 3 + .../ASTJSON/global_struct_legacy.json | 64 +++++++++++++++++++ 7 files changed, 259 insertions(+) create mode 100644 test/libsolidity/ABIJson/global_struct.sol create mode 100644 test/libsolidity/ASTJSON/global_enum.json create mode 100644 test/libsolidity/ASTJSON/global_enum.sol create mode 100644 test/libsolidity/ASTJSON/global_enum_legacy.json create mode 100644 test/libsolidity/ASTJSON/global_struct.json create mode 100644 test/libsolidity/ASTJSON/global_struct.sol create mode 100644 test/libsolidity/ASTJSON/global_struct_legacy.json diff --git a/test/libsolidity/ABIJson/global_struct.sol b/test/libsolidity/ABIJson/global_struct.sol new file mode 100644 index 000000000000..74c8fba64a66 --- /dev/null +++ b/test/libsolidity/ABIJson/global_struct.sol @@ -0,0 +1,58 @@ +pragma experimental ABIEncoderV2; +struct S { uint a; } +contract C { + function f(S calldata s) external view {} + function g(S memory s) public view {} +} +// ---- +// :C +// [ +// { +// "constant": true, +// "inputs": +// [ +// { +// "components": +// [ +// { +// "internalType": "uint256", +// "name": "a", +// "type": "uint256" +// } +// ], +// "internalType": "struct S", +// "name": "s", +// "type": "tuple" +// } +// ], +// "name": "g", +// "outputs": [], +// "payable": false, +// "stateMutability": "view", +// "type": "function" +// }, +// { +// "constant": true, +// "inputs": +// [ +// { +// "components": +// [ +// { +// "internalType": "uint256", +// "name": "a", +// "type": "uint256" +// } +// ], +// "internalType": "struct S", +// "name": "s", +// "type": "tuple" +// } +// ], +// "name": "f", +// "outputs": [], +// "payable": false, +// "stateMutability": "view", +// "type": "function" +// } +// ] diff --git a/test/libsolidity/ASTJSON/global_enum.json b/test/libsolidity/ASTJSON/global_enum.json new file mode 100644 index 000000000000..ccf3760ffabf --- /dev/null +++ b/test/libsolidity/ASTJSON/global_enum.json @@ -0,0 +1,32 @@ +{ + "absolutePath" : "a", + "exportedSymbols" : + { + "E" : + [ + 2 + ] + }, + "id" : 3, + "nodeType" : "SourceUnit", + "nodes" : + [ + { + "canonicalName" : "E", + "id" : 2, + "members" : + [ + { + "id" : 1, + "name" : "A", + "nodeType" : "EnumValue", + "src" : "9:1:1" + } + ], + "name" : "E", + "nodeType" : "EnumDefinition", + "src" : "0:12:1" + } + ], + "src" : "0:13:1" +} diff --git a/test/libsolidity/ASTJSON/global_enum.sol b/test/libsolidity/ASTJSON/global_enum.sol new file mode 100644 index 000000000000..a9c72e0c0116 --- /dev/null +++ b/test/libsolidity/ASTJSON/global_enum.sol @@ -0,0 +1,3 @@ +enum E { A } + +// ---- diff --git a/test/libsolidity/ASTJSON/global_enum_legacy.json b/test/libsolidity/ASTJSON/global_enum_legacy.json new file mode 100644 index 000000000000..fc49b6cbed2e --- /dev/null +++ b/test/libsolidity/ASTJSON/global_enum_legacy.json @@ -0,0 +1,41 @@ +{ + "attributes" : + { + "absolutePath" : "a", + "exportedSymbols" : + { + "E" : + [ + 2 + ] + } + }, + "children" : + [ + { + "attributes" : + { + "canonicalName" : "E", + "name" : "E" + }, + "children" : + [ + { + "attributes" : + { + "name" : "A" + }, + "id" : 1, + "name" : "EnumValue", + "src" : "9:1:1" + } + ], + "id" : 2, + "name" : "EnumDefinition", + "src" : "0:12:1" + } + ], + "id" : 3, + "name" : "SourceUnit", + "src" : "0:13:1" +} diff --git a/test/libsolidity/ASTJSON/global_struct.json b/test/libsolidity/ASTJSON/global_struct.json new file mode 100644 index 000000000000..63c4e463e11c --- /dev/null +++ b/test/libsolidity/ASTJSON/global_struct.json @@ -0,0 +1,58 @@ +{ + "absolutePath" : "a", + "exportedSymbols" : + { + "S" : + [ + 3 + ] + }, + "id" : 4, + "nodeType" : "SourceUnit", + "nodes" : + [ + { + "canonicalName" : "S", + "id" : 3, + "members" : + [ + { + "constant" : false, + "id" : 2, + "name" : "a", + "nodeType" : "VariableDeclaration", + "overrides" : null, + "scope" : 3, + "src" : "11:9:1", + "stateVariable" : false, + "storageLocation" : "default", + "typeDescriptions" : + { + "typeIdentifier" : "t_uint256", + "typeString" : "uint256" + }, + "typeName" : + { + "id" : 1, + "name" : "uint256", + "nodeType" : "ElementaryTypeName", + "src" : "11:7:1", + "typeDescriptions" : + { + "typeIdentifier" : "t_uint256", + "typeString" : "uint256" + } + }, + "value" : null, + "visibility" : "internal" + } + ], + "name" : "S", + "nodeType" : "StructDefinition", + "scope" : 4, + "src" : "0:23:1", + "visibility" : "public" + } + ], + "src" : "0:24:1" +} diff --git a/test/libsolidity/ASTJSON/global_struct.sol b/test/libsolidity/ASTJSON/global_struct.sol new file mode 100644 index 000000000000..4c2d002a419b --- /dev/null +++ b/test/libsolidity/ASTJSON/global_struct.sol @@ -0,0 +1,3 @@ +struct S { uint256 a; } + +// ---- diff --git a/test/libsolidity/ASTJSON/global_struct_legacy.json b/test/libsolidity/ASTJSON/global_struct_legacy.json new file mode 100644 index 000000000000..b54a31c0dc78 --- /dev/null +++ b/test/libsolidity/ASTJSON/global_struct_legacy.json @@ -0,0 +1,64 @@ +{ + "attributes" : + { + "absolutePath" : "a", + "exportedSymbols" : + { + "S" : + [ + 3 + ] + } + }, + "children" : + [ + { + "attributes" : + { + "canonicalName" : "S", + "name" : "S", + "scope" : 4, + "visibility" : "public" + }, + "children" : + [ + { + "attributes" : + { + "constant" : false, + "name" : "a", + "overrides" : null, + "scope" : 3, + "stateVariable" : false, + "storageLocation" : "default", + "type" : "uint256", + "value" : null, + "visibility" : "internal" + }, + "children" : + [ + { + "attributes" : + { + "name" : "uint256", + "type" : "uint256" + }, + "id" : 1, + "name" : "ElementaryTypeName", + "src" : "11:7:1" + } + ], + "id" : 2, + "name" : "VariableDeclaration", + "src" : "11:9:1" + } + ], + "id" : 3, + "name" : "StructDefinition", + "src" : "0:23:1" + } + ], + "id" : 4, + "name" : "SourceUnit", + "src" : "0:24:1" +} From 33f7f960cfa39f13aec802487dd0f18cefe99559 Mon Sep 17 00:00:00 2001 From: krk Date: Sun, 7 Jul 2019 17:53:03 +0200 Subject: [PATCH 013/283] Allow exponentials with signed base and unsigned power. --- Changelog.md | 1 + docs/060-breaking-changes.rst | 4 ++++ docs/types/value-types.rst | 5 +++-- libsolidity/analysis/TypeChecker.cpp | 17 +++++++++++++++++ libsolidity/ast/Types.cpp | 19 +++++++++++-------- .../exponentiation/signed_base.sol | 14 ++++++++++++++ .../exponentiation/small_exp.sol | 13 +++++++++++++ .../199_integer_unsigned_exp_signed.sol | 2 +- .../200_integer_signed_exp_unsigned.sol | 8 +++++--- .../201_integer_signed_exp_signed.sol | 7 +++---- 10 files changed, 72 insertions(+), 18 deletions(-) create mode 100644 test/libsolidity/semanticTests/exponentiation/signed_base.sol create mode 100644 test/libsolidity/semanticTests/exponentiation/small_exp.sol diff --git a/Changelog.md b/Changelog.md index d6ae4df6745d..3c64cbc167ee 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,7 @@ Breaking changes: * General: Disallow explicit conversions from external function types to ``address`` and add a member called ``address`` to them as replacement. + * Type checker: Resulting type of exponentiation is equal to the type of the base. Also allow signed types for the base. Language Features: diff --git a/docs/060-breaking-changes.rst b/docs/060-breaking-changes.rst index c6dd4112411e..6c80cc2a7e1c 100644 --- a/docs/060-breaking-changes.rst +++ b/docs/060-breaking-changes.rst @@ -29,6 +29,10 @@ Semantic and Syntactic Changes This section highlights changes that affect syntax and semantics. +* The resulting type of an exponentiation is the type of the base. It used to be the smallest type + that can hold both the type of the base and the type of the exponent, as with symmentric + operations. Additionally, signed types are allowed for the base of the exponetation. + How to update your code ======================= diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index 5f7337aaf1a7..d03a4c55f174 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -123,8 +123,9 @@ results in the same sign as its left operand (or zero) and ``a % n == -(abs(a) % Exponentiation ^^^^^^^^^^^^^^ -Exponentiation is only available for unsigned types. Please take care that the types -you are using are large enough to hold the result and prepare for potential wrapping behaviour. +Exponentiation is only available for unsigned types in the exponent. The resulting type +of an exponentiation is always equal to the type of the base. Please take care that it is +large enough to hold the result and prepare for potential wrapping behaviour. .. note:: Note that ``0**0`` is defined by the EVM as ``1``. diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 553aa0dfb62e..e0f83349346a 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1397,6 +1397,23 @@ void TypeChecker::endVisit(BinaryOperation const& _operation) "might overflow. Silence this warning by converting the literal to the " "expected type." ); + if ( + commonType->category() == Type::Category::Integer && + rightType->category() == Type::Category::Integer && + dynamic_cast(*commonType).numBits() < + dynamic_cast(*rightType).numBits() + ) + m_errorReporter.warning( + _operation.location(), + "The result type of the " + + operation + + " operation is equal to the type of the first operand (" + + commonType->toString() + + ") ignoring the (larger) type of the second operand (" + + rightType->toString() + + ") which might be unexpected. Silence this warning by either converting " + "the first or the second operand to the type of the other." + ); } } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 244cfce571ae..30323c3160e4 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -600,6 +600,17 @@ TypeResult IntegerType::binaryOperatorResult(Token _operator, Type const* _other else return nullptr; } + else if (Token::Exp == _operator) + { + if (auto otherIntType = dynamic_cast(_other)) + { + if (otherIntType->isSigned()) + return TypeResult::err("Exponentiation power is not allowed to be a signed integer type."); + } + else if (dynamic_cast(_other)) + return nullptr; + return this; + } auto commonType = Type::commonType(this, _other); //might be an integer or fixed point if (!commonType) @@ -610,14 +621,6 @@ TypeResult IntegerType::binaryOperatorResult(Token _operator, Type const* _other return commonType; if (TokenTraits::isBooleanOp(_operator)) return nullptr; - if (auto intType = dynamic_cast(commonType)) - { - if (Token::Exp == _operator && intType->isSigned()) - return TypeResult::err("Exponentiation is not allowed for signed integer types."); - } - else if (dynamic_cast(commonType)) - if (Token::Exp == _operator) - return nullptr; return commonType; } diff --git a/test/libsolidity/semanticTests/exponentiation/signed_base.sol b/test/libsolidity/semanticTests/exponentiation/signed_base.sol new file mode 100644 index 000000000000..f58c081293e6 --- /dev/null +++ b/test/libsolidity/semanticTests/exponentiation/signed_base.sol @@ -0,0 +1,14 @@ +contract test { + function f() public pure returns (int, int) { + int32 x = -3; + uint8 y1; + uint8 y2; + assembly { + y1 := 0x102 + y2 := 0x103 + } + return (x**y1, x**y2); + } +} +// ---- +// f() -> 9, -27 diff --git a/test/libsolidity/semanticTests/exponentiation/small_exp.sol b/test/libsolidity/semanticTests/exponentiation/small_exp.sol new file mode 100644 index 000000000000..9dfb5599b760 --- /dev/null +++ b/test/libsolidity/semanticTests/exponentiation/small_exp.sol @@ -0,0 +1,13 @@ +contract test { + function f() public pure returns (uint) { + uint32 x; + uint8 y; + assembly { + x := 0xfffffffffe + y := 0x102 + } + return x**y; + } +} +// ---- +// f() -> 4 diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/199_integer_unsigned_exp_signed.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/199_integer_unsigned_exp_signed.sol index fbeadfb66653..9ef74bd8e0e5 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/199_integer_unsigned_exp_signed.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/199_integer_unsigned_exp_signed.sol @@ -1,3 +1,3 @@ contract test { function() external { uint x = 3; int y = -4; x ** y; } } // ---- -// TypeError: (62-68): Operator ** not compatible with types uint256 and int256 +// TypeError: (62-68): Operator ** not compatible with types uint256 and int256. Exponentiation power is not allowed to be a signed integer type. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/200_integer_signed_exp_unsigned.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/200_integer_signed_exp_unsigned.sol index 75e920854c78..f21e1e86d82b 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/200_integer_signed_exp_unsigned.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/200_integer_signed_exp_unsigned.sol @@ -1,3 +1,5 @@ -contract test { function() external { uint x = 3; int y = -4; y ** x; } } -// ---- -// TypeError: (62-68): Operator ** not compatible with types int256 and uint256 +contract test { + function() external { uint x = 3; int y = -4; y ** x; } + function f() public pure { int16 x = 3; uint8 y = 4; x ** y; } + function g() public pure { int16 x = 3; uint16 y = 4; x ** y; } +} diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/201_integer_signed_exp_signed.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/201_integer_signed_exp_signed.sol index 9d2951b8b34c..73580e599f9e 100644 --- a/test/libsolidity/syntaxTests/nameAndTypeResolution/201_integer_signed_exp_signed.sol +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/201_integer_signed_exp_signed.sol @@ -1,9 +1,8 @@ contract test { function f() public { int x = 3; int y = 4; x ** y; } - function g() public { int16 x = 3; uint8 y = 4; x ** y; } function h() public { uint8 x = 3; int16 y = 4; x ** y; } } // ---- -// TypeError: (64-70): Operator ** not compatible with types int256 and int256. Exponentiation is not allowed for signed integer types. -// TypeError: (126-132): Operator ** not compatible with types int16 and uint8. Exponentiation is not allowed for signed integer types. -// TypeError: (188-194): Operator ** not compatible with types uint8 and int16. Exponentiation is not allowed for signed integer types. +// TypeError: (64-70): Operator ** not compatible with types int256 and int256. Exponentiation power is not allowed to be a signed integer type. +// TypeError: (126-132): Operator ** not compatible with types uint8 and int16. Exponentiation power is not allowed to be a signed integer type. +// Warning: (126-132): The result type of the exponentiation operation is equal to the type of the first operand (uint8) ignoring the (larger) type of the second operand (int16) which might be unexpected. Silence this warning by either converting the first or the second operand to the type of the other. From 9bcaeef39f62270497127814662a7198fca3cf27 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 5 Sep 2019 13:39:08 +0200 Subject: [PATCH 014/283] Fix test wrt changed json ABI sorting. --- test/libsolidity/ABIJson/global_struct.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/libsolidity/ABIJson/global_struct.sol b/test/libsolidity/ABIJson/global_struct.sol index 74c8fba64a66..71ce17c40b52 100644 --- a/test/libsolidity/ABIJson/global_struct.sol +++ b/test/libsolidity/ABIJson/global_struct.sol @@ -25,7 +25,7 @@ contract C { // "type": "tuple" // } // ], -// "name": "g", +// "name": "f", // "outputs": [], // "payable": false, // "stateMutability": "view", @@ -49,7 +49,7 @@ contract C { // "type": "tuple" // } // ], -// "name": "f", +// "name": "g", // "outputs": [], // "payable": false, // "stateMutability": "view", From 90d5c98272b6a4c0ed63ede5a591df0739c0fe34 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 6 Sep 2019 11:27:06 +0200 Subject: [PATCH 015/283] Switch to new error reporter. --- Changelog.md | 1 + solc/CommandLineInterface.cpp | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Changelog.md b/Changelog.md index 224a8331c755..2bcc5b1e238e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,7 @@ Breaking changes: * General: Disallow explicit conversions from external function types to ``address`` and add a member called ``address`` to them as replacement. * Type checker: Resulting type of exponentiation is equal to the type of the base. Also allow signed types for the base. + * Command line interface: Switch to the new error reporter by default. ``--old-reporter`` falls back to the deprecated old error reporter. Language Features: diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 79d85d82f9bb..aa2308b523de 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -150,7 +150,7 @@ static string const g_strVersion = "version"; static string const g_strIgnoreMissingFiles = "ignore-missing"; static string const g_strColor = "color"; static string const g_strNoColor = "no-color"; -static string const g_strNewReporter = "new-reporter"; +static string const g_strOldReporter = "old-reporter"; static string const g_argAbi = g_strAbi; static string const g_argPrettyJson = g_strPrettyJson; @@ -191,7 +191,7 @@ static string const g_stdinFileName = g_stdinFileNameStr; static string const g_argIgnoreMissingFiles = g_strIgnoreMissingFiles; static string const g_argColor = g_strColor; static string const g_argNoColor = g_strNoColor; -static string const g_argNewReporter = g_strNewReporter; +static string const g_argOldReporter = g_strOldReporter; /// Possible arguments to for --combined-json static set const g_combinedJsonArgs @@ -706,7 +706,7 @@ Allowed options)", ) (g_argColor.c_str(), "Force colored output.") (g_argNoColor.c_str(), "Explicitly disable colored output, disabling terminal auto-detection.") - (g_argNewReporter.c_str(), "Enables new diagnostics reporter.") + (g_argOldReporter.c_str(), "Enables old diagnostics reporter.") (g_argErrorRecovery.c_str(), "Enables additional parser error recovery.") (g_argIgnoreMissingFiles.c_str(), "Ignore missing files."); po::options_description outputComponents("Output Components"); @@ -929,10 +929,10 @@ bool CommandLineInterface::processInput() m_compiler.reset(new CompilerStack(fileReader)); unique_ptr formatter; - if (m_args.count(g_argNewReporter)) - formatter = make_unique(serr(false), m_coloredOutput); - else + if (m_args.count(g_argOldReporter)) formatter = make_unique(serr(false)); + else + formatter = make_unique(serr(false), m_coloredOutput); try { @@ -1325,10 +1325,10 @@ bool CommandLineInterface::assemble( { auto const& stack = sourceAndStack.second; unique_ptr formatter; - if (m_args.count(g_argNewReporter)) - formatter = make_unique(serr(false), m_coloredOutput); - else + if (m_args.count(g_argOldReporter)) formatter = make_unique(serr(false)); + else + formatter = make_unique(serr(false), m_coloredOutput); for (auto const& error: stack.errors()) { From 5d69bdf81e2dce46d09fcd1fef3b412394f01a49 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 6 Sep 2019 12:38:55 +0200 Subject: [PATCH 016/283] Remove ASTPrinter. --- Changelog.md | 1 + docs/using-the-compiler.rst | 2 +- libsolidity/CMakeLists.txt | 2 - libsolidity/ast/ASTPrinter.cpp | 656 --------------------------------- libsolidity/ast/ASTPrinter.h | 157 -------- solc/CommandLineInterface.cpp | 32 +- 6 files changed, 6 insertions(+), 844 deletions(-) delete mode 100644 libsolidity/ast/ASTPrinter.cpp delete mode 100644 libsolidity/ast/ASTPrinter.h diff --git a/Changelog.md b/Changelog.md index 224a8331c755..84c8dffc284d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ ### 0.6.0 (unreleased) Breaking changes: + * Commandline interface: remove the text-based ast printer (``--ast``). * General: Disallow explicit conversions from external function types to ``address`` and add a member called ``address`` to them as replacement. * Type checker: Resulting type of exponentiation is equal to the type of the base. Also allow signed types for the base. diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 5b2e9b8ca847..b8c518bc5d7a 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -14,7 +14,7 @@ Using the Commandline Compiler One of the build targets of the Solidity repository is ``solc``, the solidity commandline compiler. Using ``solc --help`` provides you with an explanation of all options. The compiler can produce various outputs, ranging from simple binaries and assembly over an abstract syntax tree (parse tree) to estimations of gas usage. -If you only want to compile a single file, you run it as ``solc --bin sourceFile.sol`` and it will print the binary. If you want to get some of the more advanced output variants of ``solc``, it is probably better to tell it to output everything to separate files using ``solc -o outputDirectory --bin --ast --asm sourceFile.sol``. +If you only want to compile a single file, you run it as ``solc --bin sourceFile.sol`` and it will print the binary. If you want to get some of the more advanced output variants of ``solc``, it is probably better to tell it to output everything to separate files using ``solc -o outputDirectory --bin --ast-json --asm sourceFile.sol``. Before you deploy your contract, activate the optimizer when compiling using ``solc --optimize --bin sourceFile.sol``. By default, the optimizer will optimize the contract assuming it is called 200 times across its lifetime diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 81e86e6219d7..384d3cb6c5ee 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -39,8 +39,6 @@ set(sources ast/ASTForward.h ast/ASTJsonConverter.cpp ast/ASTJsonConverter.h - ast/ASTPrinter.cpp - ast/ASTPrinter.h ast/ASTVisitor.h ast/ExperimentalFeatures.h ast/Types.cpp diff --git a/libsolidity/ast/ASTPrinter.cpp b/libsolidity/ast/ASTPrinter.cpp deleted file mode 100644 index 1d9f40876845..000000000000 --- a/libsolidity/ast/ASTPrinter.cpp +++ /dev/null @@ -1,656 +0,0 @@ -/* - 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 . -*/ -/** - * @author Christian - * @date 2014 - * Pretty-printer for the abstract syntax tree (the "pretty" is arguable), used for debugging. - */ - -#include - -#include -#include -#include - -using namespace std; -using namespace langutil; - -namespace dev -{ -namespace solidity -{ - -ASTPrinter::ASTPrinter( - ASTNode const& _ast, - string const& _source, - GasEstimator::ASTGasConsumption const& _gasCosts -): m_indentation(0), m_source(_source), m_ast(&_ast), m_gasCosts(_gasCosts) -{ -} - -void ASTPrinter::print(ostream& _stream) -{ - m_ostream = &_stream; - m_ast->accept(*this); - m_ostream = nullptr; -} - - -bool ASTPrinter::visit(PragmaDirective const& _node) -{ - writeLine("PragmaDirective"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(ImportDirective const& _node) -{ - writeLine("ImportDirective \"" + _node.path() + "\""); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(ContractDefinition const& _node) -{ - writeLine("ContractDefinition \"" + _node.name() + "\""); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(InheritanceSpecifier const& _node) -{ - writeLine("InheritanceSpecifier"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(UsingForDirective const& _node) -{ - writeLine("UsingForDirective"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(StructDefinition const& _node) -{ - writeLine("StructDefinition \"" + _node.name() + "\""); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(EnumDefinition const& _node) -{ - writeLine("EnumDefinition \"" + _node.name() + "\""); - return goDeeper(); -} - -bool ASTPrinter::visit(EnumValue const& _node) -{ - writeLine("EnumValue \"" + _node.name() + "\""); - return goDeeper(); -} - -bool ASTPrinter::visit(ParameterList const& _node) -{ - writeLine("ParameterList"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(OverrideSpecifier const& _node) -{ - writeLine("OverrideSpecifier"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(FunctionDefinition const& _node) -{ - writeLine( - "FunctionDefinition \"" + - _node.name() + - "\"" + - (_node.isPublic() ? " - public" : "") + - (_node.stateMutability() == StateMutability::View ? " - const" : "") - ); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(VariableDeclaration const& _node) -{ - writeLine("VariableDeclaration \"" + _node.name() + "\""); - *m_ostream << indentation() << ( - _node.annotation().type ? - string(" Type: ") + _node.annotation().type->toString() : - string(" Type unknown.") - ) << "\n"; - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(ModifierDefinition const& _node) -{ - writeLine("ModifierDefinition \"" + _node.name() + "\""); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(ModifierInvocation const& _node) -{ - writeLine("ModifierInvocation \"" + _node.name()->name() + "\""); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(EventDefinition const& _node) -{ - writeLine("EventDefinition \"" + _node.name() + "\""); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(ElementaryTypeName const& _node) -{ - writeLine(string("ElementaryTypeName ") + _node.typeName().toString()); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(UserDefinedTypeName const& _node) -{ - writeLine("UserDefinedTypeName \"" + boost::algorithm::join(_node.namePath(), ".") + "\""); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(FunctionTypeName const& _node) -{ - writeLine("FunctionTypeName"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(Mapping const& _node) -{ - writeLine("Mapping"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(ArrayTypeName const& _node) -{ - writeLine("ArrayTypeName"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(InlineAssembly const& _node) -{ - writeLine("InlineAssembly"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(Block const& _node) -{ - writeLine("Block"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(PlaceholderStatement const& _node) -{ - writeLine("PlaceholderStatement"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(IfStatement const& _node) -{ - writeLine("IfStatement"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(WhileStatement const& _node) -{ - writeLine(_node.isDoWhile() ? "DoWhileStatement" : "WhileStatement"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(ForStatement const& _node) -{ - writeLine("ForStatement"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(Continue const& _node) -{ - writeLine("Continue"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(Break const& _node) -{ - writeLine("Break"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(Return const& _node) -{ - writeLine("Return"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(Throw const& _node) -{ - writeLine("Throw"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(EmitStatement const& _node) -{ - writeLine("EmitStatement"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(VariableDeclarationStatement const& _node) -{ - writeLine("VariableDeclarationStatement"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(ExpressionStatement const& _node) -{ - writeLine("ExpressionStatement"); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(Conditional const& _node) -{ - writeLine("Conditional"); - printType(_node); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(Assignment const& _node) -{ - writeLine(string("Assignment using operator ") + TokenTraits::toString(_node.assignmentOperator())); - printType(_node); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(TupleExpression const& _node) -{ - writeLine(string("TupleExpression")); - printType(_node); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(UnaryOperation const& _node) -{ - writeLine( - string("UnaryOperation (") + - (_node.isPrefixOperation() ? "prefix" : "postfix") + - ") " + - TokenTraits::toString(_node.getOperator()) - ); - printType(_node); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(BinaryOperation const& _node) -{ - writeLine(string("BinaryOperation using operator ") + TokenTraits::toString(_node.getOperator())); - printType(_node); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(FunctionCall const& _node) -{ - writeLine("FunctionCall"); - printType(_node); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(NewExpression const& _node) -{ - writeLine("NewExpression"); - printType(_node); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(MemberAccess const& _node) -{ - writeLine("MemberAccess to member " + _node.memberName()); - printType(_node); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(IndexAccess const& _node) -{ - writeLine("IndexAccess"); - printType(_node); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(Identifier const& _node) -{ - writeLine(string("Identifier ") + _node.name()); - printType(_node); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(ElementaryTypeNameExpression const& _node) -{ - writeLine(string("ElementaryTypeNameExpression ") + _node.typeName().toString()); - printType(_node); - printSourcePart(_node); - return goDeeper(); -} - -bool ASTPrinter::visit(Literal const& _node) -{ - char const* tokenString = TokenTraits::toString(_node.token()); - if (!tokenString) - tokenString = "[no token]"; - writeLine(string("Literal, token: ") + tokenString + " value: " + _node.value()); - printType(_node); - printSourcePart(_node); - return goDeeper(); -} - -void ASTPrinter::endVisit(PragmaDirective const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(ImportDirective const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(ContractDefinition const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(InheritanceSpecifier const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(UsingForDirective const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(StructDefinition const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(EnumDefinition const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(EnumValue const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(ParameterList const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(OverrideSpecifier const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(FunctionDefinition const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(VariableDeclaration const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(ModifierDefinition const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(ModifierInvocation const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(EventDefinition const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(ElementaryTypeName const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(UserDefinedTypeName const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(FunctionTypeName const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(Mapping const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(ArrayTypeName const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(InlineAssembly const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(Block const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(PlaceholderStatement const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(IfStatement const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(WhileStatement const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(ForStatement const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(Continue const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(Break const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(Return const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(Throw const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(EmitStatement const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(VariableDeclarationStatement const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(ExpressionStatement const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(Conditional const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(Assignment const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(TupleExpression const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(UnaryOperation const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(BinaryOperation const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(FunctionCall const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(NewExpression const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(MemberAccess const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(IndexAccess const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(Identifier const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(ElementaryTypeNameExpression const&) -{ - m_indentation--; -} - -void ASTPrinter::endVisit(Literal const&) -{ - m_indentation--; -} - -void ASTPrinter::printSourcePart(ASTNode const& _node) -{ - if (m_gasCosts.count(&_node)) - *m_ostream << indentation() << " Gas costs: " << m_gasCosts.at(&_node) << endl; - if (!m_source.empty()) - { - SourceLocation const& location(_node.location()); - *m_ostream << - indentation() << - " Source: " << - Json::valueToQuotedString(m_source.substr(location.start, location.end - location.start).c_str()) << - endl; - } -} - -void ASTPrinter::printType(Expression const& _expression) -{ - if (_expression.annotation().type) - *m_ostream << indentation() << " Type: " << _expression.annotation().type->toString() << "\n"; - else - *m_ostream << indentation() << " Type unknown.\n"; -} - -string ASTPrinter::indentation() const -{ - return string(m_indentation * 2, ' '); -} - -void ASTPrinter::writeLine(string const& _line) -{ - *m_ostream << indentation() << _line << endl; -} - -} -} diff --git a/libsolidity/ast/ASTPrinter.h b/libsolidity/ast/ASTPrinter.h deleted file mode 100644 index 697db4378ee1..000000000000 --- a/libsolidity/ast/ASTPrinter.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - 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 . -*/ -/** - * @author Christian - * @date 2014 - * Pretty-printer for the abstract syntax tree (the "pretty" is arguable), used for debugging. - */ - -#pragma once - -#include -#include -#include - -namespace dev -{ -namespace solidity -{ - -/** - * Pretty-printer for the abstract syntax tree (the "pretty" is arguable) for debugging purposes. - */ -class ASTPrinter: public ASTConstVisitor -{ -public: - /// Create a printer for the given abstract syntax tree. If the source is specified, - /// the corresponding parts of the source are printed with each node. - ASTPrinter( - ASTNode const& _ast, - std::string const& _source = std::string(), - GasEstimator::ASTGasConsumption const& _gasCosts = GasEstimator::ASTGasConsumption() - ); - /// Output the string representation of the AST to _stream. - void print(std::ostream& _stream); - - bool visit(PragmaDirective const& _node) override; - bool visit(ImportDirective const& _node) override; - bool visit(ContractDefinition const& _node) override; - bool visit(InheritanceSpecifier const& _node) override; - bool visit(UsingForDirective const& _node) override; - bool visit(StructDefinition const& _node) override; - bool visit(EnumDefinition const& _node) override; - bool visit(EnumValue const& _node) override; - bool visit(ParameterList const& _node) override; - bool visit(OverrideSpecifier const& _node) override; - bool visit(FunctionDefinition const& _node) override; - bool visit(VariableDeclaration const& _node) override; - bool visit(ModifierDefinition const& _node) override; - bool visit(ModifierInvocation const& _node) override; - bool visit(EventDefinition const& _node) override; - bool visit(ElementaryTypeName const& _node) override; - bool visit(UserDefinedTypeName const& _node) override; - bool visit(FunctionTypeName const& _node) override; - bool visit(Mapping const& _node) override; - bool visit(ArrayTypeName const& _node) override; - bool visit(InlineAssembly const& _node) override; - bool visit(Block const& _node) override; - bool visit(PlaceholderStatement const& _node) override; - bool visit(IfStatement const& _node) override; - bool visit(WhileStatement const& _node) override; - bool visit(ForStatement const& _node) override; - bool visit(Continue const& _node) override; - bool visit(Break const& _node) override; - bool visit(Return const& _node) override; - bool visit(Throw const& _node) override; - bool visit(EmitStatement const& _node) override; - bool visit(VariableDeclarationStatement const& _node) override; - bool visit(ExpressionStatement const& _node) override; - bool visit(Conditional const& _node) override; - bool visit(Assignment const& _node) override; - bool visit(TupleExpression const& _node) override; - bool visit(UnaryOperation const& _node) override; - bool visit(BinaryOperation const& _node) override; - bool visit(FunctionCall const& _node) override; - bool visit(NewExpression const& _node) override; - bool visit(MemberAccess const& _node) override; - bool visit(IndexAccess const& _node) override; - bool visit(Identifier const& _node) override; - bool visit(ElementaryTypeNameExpression const& _node) override; - bool visit(Literal const& _node) override; - - void endVisit(PragmaDirective const&) override; - void endVisit(ImportDirective const&) override; - void endVisit(ContractDefinition const&) override; - void endVisit(InheritanceSpecifier const&) override; - void endVisit(UsingForDirective const&) override; - void endVisit(StructDefinition const&) override; - void endVisit(EnumDefinition const&) override; - void endVisit(EnumValue const&) override; - void endVisit(ParameterList const&) override; - void endVisit(OverrideSpecifier const&) override; - void endVisit(FunctionDefinition const&) override; - void endVisit(VariableDeclaration const&) override; - void endVisit(ModifierDefinition const&) override; - void endVisit(ModifierInvocation const&) override; - void endVisit(EventDefinition const&) override; - void endVisit(ElementaryTypeName const&) override; - void endVisit(UserDefinedTypeName const&) override; - void endVisit(FunctionTypeName const&) override; - void endVisit(Mapping const&) override; - void endVisit(ArrayTypeName const&) override; - void endVisit(InlineAssembly const&) override; - void endVisit(Block const&) override; - void endVisit(PlaceholderStatement const&) override; - void endVisit(IfStatement const&) override; - void endVisit(WhileStatement const&) override; - void endVisit(ForStatement const&) override; - void endVisit(Continue const&) override; - void endVisit(Break const&) override; - void endVisit(Return const&) override; - void endVisit(Throw const&) override; - void endVisit(EmitStatement const&) override; - void endVisit(VariableDeclarationStatement const&) override; - void endVisit(ExpressionStatement const&) override; - void endVisit(Conditional const&) override; - void endVisit(Assignment const&) override; - void endVisit(TupleExpression const&) override; - void endVisit(UnaryOperation const&) override; - void endVisit(BinaryOperation const&) override; - void endVisit(FunctionCall const&) override; - void endVisit(NewExpression const&) override; - void endVisit(MemberAccess const&) override; - void endVisit(IndexAccess const&) override; - void endVisit(Identifier const&) override; - void endVisit(ElementaryTypeNameExpression const&) override; - void endVisit(Literal const&) override; - -private: - void printSourcePart(ASTNode const& _node); - void printType(Expression const& _expression); - std::string indentation() const; - void writeLine(std::string const& _line); - bool goDeeper() { m_indentation++; return true; } - - int m_indentation; - std::string m_source; - ASTNode const* m_ast; - GasEstimator::ASTGasConsumption m_gasCosts; - std::ostream* m_ostream = nullptr; -}; - -} -} diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 79d85d82f9bb..f73bccba4cb4 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -27,7 +27,6 @@ #include #include -#include #include #include #include @@ -158,7 +157,6 @@ static string const g_argAllowPaths = g_strAllowPaths; static string const g_argAsm = g_strAsm; static string const g_argAsmJson = g_strAsmJson; static string const g_argAssemble = g_strAssemble; -static string const g_argAst = g_strAst; static string const g_argAstCompactJson = g_strAstCompactJson; static string const g_argAstJson = g_strAstJson; static string const g_argBinary = g_strBinary; @@ -711,7 +709,6 @@ Allowed options)", (g_argIgnoreMissingFiles.c_str(), "Ignore missing files."); po::options_description outputComponents("Output Components"); outputComponents.add_options() - (g_argAst.c_str(), "AST of all source files.") (g_argAstJson.c_str(), "AST of all source files in JSON format.") (g_argAstCompactJson.c_str(), "AST of all source files in a compact JSON format.") (g_argAsm.c_str(), "EVM assembly of the contracts.") @@ -1108,9 +1105,7 @@ void CommandLineInterface::handleAst(string const& _argStr) { string title; - if (_argStr == g_argAst) - title = "Syntax trees:"; - else if (_argStr == g_argAstJson) + if (_argStr == g_argAstJson) title = "JSON AST:"; else if (_argStr == g_argAstCompactJson) title = "JSON AST (compact format):"; @@ -1143,16 +1138,8 @@ void CommandLineInterface::handleAst(string const& _argStr) { stringstream data; string postfix = ""; - if (_argStr == g_argAst) - { - ASTPrinter printer(m_compiler->ast(sourceCode.first), sourceCode.second); - printer.print(data); - } - else - { - ASTJsonConverter(legacyFormat, m_compiler->sourceIndices()).print(data, m_compiler->ast(sourceCode.first)); - postfix += "_json"; - } + ASTJsonConverter(legacyFormat, m_compiler->sourceIndices()).print(data, m_compiler->ast(sourceCode.first)); + postfix += "_json"; boost::filesystem::path path(sourceCode.first); createFile(path.filename().string() + postfix + ".ast", data.str()); } @@ -1163,17 +1150,7 @@ void CommandLineInterface::handleAst(string const& _argStr) for (auto const& sourceCode: m_sourceCodes) { sout() << endl << "======= " << sourceCode.first << " =======" << endl; - if (_argStr == g_argAst) - { - ASTPrinter printer( - m_compiler->ast(sourceCode.first), - sourceCode.second, - gasCosts - ); - printer.print(sout()); - } - else - ASTJsonConverter(legacyFormat, m_compiler->sourceIndices()).print(sout(), m_compiler->ast(sourceCode.first)); + ASTJsonConverter(legacyFormat, m_compiler->sourceIndices()).print(sout(), m_compiler->ast(sourceCode.first)); } } } @@ -1398,7 +1375,6 @@ void CommandLineInterface::outputCompilationResults() handleCombinedJSON(); // do we need AST output? - handleAst(g_argAst); handleAst(g_argAstJson); handleAst(g_argAstCompactJson); From f84371b2e0885c51d11701d64b3b6c4121f619ee Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 6 Sep 2019 11:52:58 +0200 Subject: [PATCH 017/283] Fix command line tests for new error reporter. --- test/cmdlineTests.sh | 5 ++++- test/cmdlineTests/recovery_ast_constructor/err | 18 ++++++++++++------ test/cmdlineTests/strict_asm_jump/err | 8 +++++--- test/cmdlineTests/too_long_line/err | 17 +++++++++++------ .../too_long_line_both_sides_short/err | 17 +++++++++++------ test/cmdlineTests/too_long_line_edge_in/err | 17 +++++++++++------ test/cmdlineTests/too_long_line_edge_out/err | 17 +++++++++++------ test/cmdlineTests/too_long_line_left_short/err | 17 +++++++++++------ test/cmdlineTests/too_long_line_multiline/err | 17 +++++++++++------ .../cmdlineTests/too_long_line_right_short/err | 17 +++++++++++------ 10 files changed, 98 insertions(+), 52 deletions(-) diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index a9ab91bc796b..7cd25229775d 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -74,7 +74,7 @@ function compileFull() set +e "$SOLC" $FULLARGS $files >/dev/null 2>"$stderr_path" local exit_code=$? - local errors=$(grep -v -E 'Warning: This is a pre-release compiler version|Warning: Experimental features are turned on|pragma experimental ABIEncoderV2|\^-------------------------------\^' < "$stderr_path") + local errors=$(grep -v -E 'Warning: This is a pre-release compiler version|Warning: Experimental features are turned on|pragma experimental ABIEncoderV2|^ +--> |^ +\||^[0-9]+ +\|' < "$stderr_path") set -e rm "$stderr_path" @@ -156,6 +156,9 @@ function test_solc_behaviour() else sed -i -e '/^Warning: This is a pre-release compiler version, please do not use it in production./d' "$stderr_path" sed -i -e 's/ Consider adding "pragma .*$//' "$stderr_path" + # Remove trailing empty lines. Needs a line break to make OSX sed happy. + sed -i -e '1{/^$/d +}' "$stderr_path" fi # Remove path to cpp file sed -i -e 's/^\(Exception while assembling:\).*/\1/' "$stderr_path" diff --git a/test/cmdlineTests/recovery_ast_constructor/err b/test/cmdlineTests/recovery_ast_constructor/err index 1cdca63230c2..81c911386d01 100644 --- a/test/cmdlineTests/recovery_ast_constructor/err +++ b/test/cmdlineTests/recovery_ast_constructor/err @@ -1,8 +1,14 @@ -recovery_ast_constructor/input.sol:5:27: Error: Expected primary expression. - balances[tx.origin] = ; // missing RHS. - ^ -recovery_ast_constructor/input.sol:5:27: Warning: Recovered in Statement at ';'. - balances[tx.origin] = ; // missing RHS. - ^ +Error: Expected primary expression. + --> recovery_ast_constructor/input.sol:5:27: + | +5 | balances[tx.origin] = ; // missing RHS. + | ^ + +Warning: Recovered in Statement at ';'. + --> recovery_ast_constructor/input.sol:5:27: + | +5 | balances[tx.origin] = ; // missing RHS. + | ^ + Compilation halted after AST generation due to errors. diff --git a/test/cmdlineTests/strict_asm_jump/err b/test/cmdlineTests/strict_asm_jump/err index 95dd70c750c8..8463daa8211c 100644 --- a/test/cmdlineTests/strict_asm_jump/err +++ b/test/cmdlineTests/strict_asm_jump/err @@ -1,4 +1,6 @@ Warning: Yul and its optimizer are still experimental. Please use the output with care. -strict_asm_jump/input.sol:1:3: Error: Function not found. -{ jump(1) } - ^--^ +Error: Function not found. + --> strict_asm_jump/input.sol:1:3: + | +1 | { jump(1) } + | ^^^^ diff --git a/test/cmdlineTests/too_long_line/err b/test/cmdlineTests/too_long_line/err index bfbc8e1ed5e9..6683949aeda8 100644 --- a/test/cmdlineTests/too_long_line/err +++ b/test/cmdlineTests/too_long_line/err @@ -1,6 +1,11 @@ -too_long_line/input.sol:1:1: Warning: Source file does not specify required compiler version! -contract C { -^ (Relevant source part starts here and spans across multiple lines). -too_long_line/input.sol:2:164: Error: Identifier not found or not unique. - ... ffffffffffffffffffffffffffffffffff(announcementType Type, string Announcement, string ... - ^--------------^ +Warning: Source file does not specify required compiler version! + --> too_long_line/input.sol:1:1: + | +1 | contract C { + | ^ (Relevant source part starts here and spans across multiple lines). + +Error: Identifier not found or not unique. + --> too_long_line/input.sol:2:164: + | +2 | ... ffffffffffffffffffffffffffffffffff(announcementType Type, string Announcement, string ... + | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_both_sides_short/err b/test/cmdlineTests/too_long_line_both_sides_short/err index 2868fcb120b9..aeb7c4b7d2fb 100644 --- a/test/cmdlineTests/too_long_line_both_sides_short/err +++ b/test/cmdlineTests/too_long_line_both_sides_short/err @@ -1,6 +1,11 @@ -too_long_line_both_sides_short/input.sol:1:1: Warning: Source file does not specify required compiler version! -contract C { -^ (Relevant source part starts here and spans across multiple lines). -too_long_line_both_sides_short/input.sol:2:15: Error: Identifier not found or not unique. - function f(announcementTypeXXXXXXXXXXXXXXXXXXX ... XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Type, - ^-------------------------------------------------------------------------^ +Warning: Source file does not specify required compiler version! + --> too_long_line_both_sides_short/input.sol:1:1: + | +1 | contract C { + | ^ (Relevant source part starts here and spans across multiple lines). + +Error: Identifier not found or not unique. + --> too_long_line_both_sides_short/input.sol:2:15: + | +2 | function f(announcementTypeXXXXXXXXXXXXXXXXXXX ... XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Type, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_edge_in/err b/test/cmdlineTests/too_long_line_edge_in/err index 626451e11ad0..edcac5dee594 100644 --- a/test/cmdlineTests/too_long_line_edge_in/err +++ b/test/cmdlineTests/too_long_line_edge_in/err @@ -1,6 +1,11 @@ -too_long_line_edge_in/input.sol:1:1: Warning: Source file does not specify required compiler version! -contract C { -^ (Relevant source part starts here and spans across multiple lines). -too_long_line_edge_in/input.sol:2:36: Error: Identifier not found or not unique. - function ffffffffffffffffffffff(announcementTypeTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT Ty, string A) onlyOwner external { - ^----------------------------------------------------------------------------------------------^ +Warning: Source file does not specify required compiler version! + --> too_long_line_edge_in/input.sol:1:1: + | +1 | contract C { + | ^ (Relevant source part starts here and spans across multiple lines). + +Error: Identifier not found or not unique. + --> too_long_line_edge_in/input.sol:2:36: + | +2 | function ffffffffffffffffffffff(announcementTypeTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT Ty, string A) onlyOwner external { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_edge_out/err b/test/cmdlineTests/too_long_line_edge_out/err index 7a4f935ad6be..17856f629880 100644 --- a/test/cmdlineTests/too_long_line_edge_out/err +++ b/test/cmdlineTests/too_long_line_edge_out/err @@ -1,6 +1,11 @@ -too_long_line_edge_out/input.sol:1:1: Warning: Source file does not specify required compiler version! -contract C { -^ (Relevant source part starts here and spans across multiple lines). -too_long_line_edge_out/input.sol:2:37: Error: Identifier not found or not unique. - ... function fffffffffffffffffffffff(announcementTypeTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT Typ, string A) onlyOwner external ... - ^----------------------------------------------------------------------------------------------^ +Warning: Source file does not specify required compiler version! + --> too_long_line_edge_out/input.sol:1:1: + | +1 | contract C { + | ^ (Relevant source part starts here and spans across multiple lines). + +Error: Identifier not found or not unique. + --> too_long_line_edge_out/input.sol:2:37: + | +2 | ... function fffffffffffffffffffffff(announcementTypeTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT Typ, string A) onlyOwner external ... + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_left_short/err b/test/cmdlineTests/too_long_line_left_short/err index 4aa830b6d39a..931c208c0931 100644 --- a/test/cmdlineTests/too_long_line_left_short/err +++ b/test/cmdlineTests/too_long_line_left_short/err @@ -1,6 +1,11 @@ -too_long_line_left_short/input.sol:1:1: Warning: Source file does not specify required compiler version! -contract C { -^ (Relevant source part starts here and spans across multiple lines). -too_long_line_left_short/input.sol:2:15: Error: Identifier not found or not unique. - function f(announcementType Type, string Announcement, string ... - ^--------------^ +Warning: Source file does not specify required compiler version! + --> too_long_line_left_short/input.sol:1:1: + | +1 | contract C { + | ^ (Relevant source part starts here and spans across multiple lines). + +Error: Identifier not found or not unique. + --> too_long_line_left_short/input.sol:2:15: + | +2 | function f(announcementType Type, string Announcement, string ... + | ^^^^^^^^^^^^^^^^ diff --git a/test/cmdlineTests/too_long_line_multiline/err b/test/cmdlineTests/too_long_line_multiline/err index c00e43fd7303..67ebcff07996 100644 --- a/test/cmdlineTests/too_long_line_multiline/err +++ b/test/cmdlineTests/too_long_line_multiline/err @@ -1,6 +1,11 @@ -too_long_line_multiline/input.sol:2:5: Error: No visibility specified. Did you intend to add "public"? - function f() returns (byte _b, byte ... _b7, bytes22 _b22, bytes32 _b32) { - ^ (Relevant source part starts here and spans across multiple lines). -too_long_line_multiline/input.sol:1:1: Warning: Source file does not specify required compiler version! -contract C { -^ (Relevant source part starts here and spans across multiple lines). +Error: No visibility specified. Did you intend to add "public"? + --> too_long_line_multiline/input.sol:2:5: + | +2 | function f() returns (byte _b, byte ... _b7, bytes22 _b22, bytes32 _b32) { + | ^ (Relevant source part starts here and spans across multiple lines). + +Warning: Source file does not specify required compiler version! + --> too_long_line_multiline/input.sol:1:1: + | +1 | contract C { + | ^ (Relevant source part starts here and spans across multiple lines). diff --git a/test/cmdlineTests/too_long_line_right_short/err b/test/cmdlineTests/too_long_line_right_short/err index ed9925655014..5f291b9792ea 100644 --- a/test/cmdlineTests/too_long_line_right_short/err +++ b/test/cmdlineTests/too_long_line_right_short/err @@ -1,6 +1,11 @@ -too_long_line_right_short/input.sol:1:1: Warning: Source file does not specify required compiler version! -contract C { -^ (Relevant source part starts here and spans across multiple lines). -too_long_line_right_short/input.sol:2:164: Error: Identifier not found or not unique. - ... ffffffffffffffffffffffffffffffffff(announcementType Type, - ^--------------^ +Warning: Source file does not specify required compiler version! + --> too_long_line_right_short/input.sol:1:1: + | +1 | contract C { + | ^ (Relevant source part starts here and spans across multiple lines). + +Error: Identifier not found or not unique. + --> too_long_line_right_short/input.sol:2:164: + | +2 | ... ffffffffffffffffffffffffffffffffff(announcementType Type, + | ^^^^^^^^^^^^^^^^ From 998f7de2c8d5f515641f15a5543268ed6c09b783 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 6 Sep 2019 13:39:29 +0200 Subject: [PATCH 018/283] Change command line test from --ast to --ast-json. --- scripts/check_style.sh | 2 +- .../recovery_ast_constructor/args | 2 +- .../recovery_ast_constructor/output | 272 ++++++++++++++++-- 3 files changed, 243 insertions(+), 33 deletions(-) diff --git a/scripts/check_style.sh b/scripts/check_style.sh index 0f9a8096ed61..4e56143fa202 100755 --- a/scripts/check_style.sh +++ b/scripts/check_style.sh @@ -6,7 +6,7 @@ REPO_ROOT="$(dirname "$0")"/.. cd $REPO_ROOT -WHITESPACE=$(git grep -n -I -E "^.*[[:space:]]+$" | grep -v "test/libsolidity/ASTJSON\|test/libsolidity/ASTRecoveryTests\|test/compilationTests/zeppelin/LICENSE") +WHITESPACE=$(git grep -n -I -E "^.*[[:space:]]+$" | grep -v "test/libsolidity/ASTJSON\|test/libsolidity/ASTRecoveryTests\|test/compilationTests/zeppelin/LICENSE\|test/cmdlineTests/recovery_ast_constructor/output") if [[ "$WHITESPACE" != "" ]] then diff --git a/test/cmdlineTests/recovery_ast_constructor/args b/test/cmdlineTests/recovery_ast_constructor/args index bd706404927d..c5786054e5c2 100644 --- a/test/cmdlineTests/recovery_ast_constructor/args +++ b/test/cmdlineTests/recovery_ast_constructor/args @@ -1 +1 @@ ---error-recovery --ast --hashes +--error-recovery --ast-json --hashes diff --git a/test/cmdlineTests/recovery_ast_constructor/output b/test/cmdlineTests/recovery_ast_constructor/output index 98a17ceafdac..a35fe35e1902 100644 --- a/test/cmdlineTests/recovery_ast_constructor/output +++ b/test/cmdlineTests/recovery_ast_constructor/output @@ -1,34 +1,244 @@ -Syntax trees: +JSON AST: ======= recovery_ast_constructor/input.sol ======= -PragmaDirective - Source: "pragma solidity >=0.0.0;" -ContractDefinition "Error1" - Source: "contract Error1 {\n constructor() public {\n balances[tx.origin] = ; // missing RHS.\n }\n\n // Without error recovery we stop due to the above error.\n // Error recovery however recovers at the above ';'\n // There should be an AST for the above, albeit with error\n // nodes.\n\n // This function parses properly and should give AST info.\n function five() public view returns(uint) {\n return 5;\n }\n}" - FunctionDefinition "" - public - Source: "constructor() public {\n balances[tx.origin] = ; // missing RHS.\n }" - ParameterList - Source: "()" - ParameterList - Source: "" - Block - Source: "{\n balances[tx.origin] = ; // missing RHS.\n }" - FunctionDefinition "five" - public - const - Source: "function five() public view returns(uint) {\n return 5;\n }" - ParameterList - Source: "()" - ParameterList - Source: "(uint)" - VariableDeclaration "" - Type: uint256 - Source: "uint" - ElementaryTypeName uint - Source: "uint" - Block - Source: "{\n return 5;\n }" - Return - Source: "return 5" - Literal, token: [no token] value: 5 - Type: int_const 5 - Source: "5" +{ + "attributes" : + { + "absolutePath" : "recovery_ast_constructor/input.sol", + "exportedSymbols" : + { + "Error1" : + [ + 18 + ] + } + }, + "children" : + [ + { + "attributes" : + { + "literals" : + [ + "solidity", + ">=", + "0.0", + ".0" + ] + }, + "id" : 1, + "name" : "PragmaDirective", + "src" : "0:24:0" + }, + { + "attributes" : + { + "baseContracts" : + [ + null + ], + "contractDependencies" : + [ + null + ], + "contractKind" : "contract", + "documentation" : null, + "fullyImplemented" : true, + "linearizedBaseContracts" : + [ + 18 + ], + "name" : "Error1", + "scope" : 19 + }, + "children" : + [ + { + "attributes" : + { + "documentation" : null, + "implemented" : true, + "isConstructor" : true, + "kind" : "constructor", + "modifiers" : + [ + null + ], + "name" : "", + "overrides" : null, + "scope" : 18, + "stateMutability" : "nonpayable", + "superFunction" : null, + "visibility" : "public" + }, + "children" : + [ + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 2, + "name" : "ParameterList", + "src" : "57:2:0" + }, + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 3, + "name" : "ParameterList", + "src" : "67:0:0" + }, + { + "attributes" : + { + "statements" : + [ + null + ] + }, + "children" : [], + "id" : 8, + "name" : "Block", + "src" : "67:49:0" + } + ], + "id" : 9, + "name" : "FunctionDefinition", + "src" : "46:70:0" + }, + { + "attributes" : + { + "documentation" : null, + "implemented" : true, + "isConstructor" : false, + "kind" : "function", + "modifiers" : + [ + null + ], + "name" : "five", + "overrides" : null, + "scope" : 18, + "stateMutability" : "view", + "superFunction" : null, + "visibility" : "public" + }, + "children" : + [ + { + "attributes" : + { + "parameters" : + [ + null + ] + }, + "children" : [], + "id" : 10, + "name" : "ParameterList", + "src" : "382:2:0" + }, + { + "children" : + [ + { + "attributes" : + { + "constant" : false, + "name" : "", + "overrides" : null, + "scope" : 17, + "stateVariable" : false, + "storageLocation" : "default", + "type" : "uint256", + "value" : null, + "visibility" : "internal" + }, + "children" : + [ + { + "attributes" : + { + "name" : "uint", + "type" : "uint256" + }, + "id" : 11, + "name" : "ElementaryTypeName", + "src" : "405:4:0" + } + ], + "id" : 12, + "name" : "VariableDeclaration", + "src" : "405:4:0" + } + ], + "id" : 13, + "name" : "ParameterList", + "src" : "404:6:0" + }, + { + "children" : + [ + { + "attributes" : + { + "functionReturnParameters" : 13 + }, + "children" : + [ + { + "attributes" : + { + "argumentTypes" : null, + "hexvalue" : "35", + "isConstant" : false, + "isLValue" : false, + "isPure" : true, + "lValueRequested" : false, + "subdenomination" : null, + "token" : "number", + "type" : "int_const 5", + "value" : "5" + }, + "id" : 14, + "name" : "Literal", + "src" : "424:1:0" + } + ], + "id" : 15, + "name" : "Return", + "src" : "417:8:0" + } + ], + "id" : 16, + "name" : "Block", + "src" : "411:19:0" + } + ], + "id" : 17, + "name" : "FunctionDefinition", + "src" : "369:61:0" + } + ], + "id" : 18, + "name" : "ContractDefinition", + "src" : "26:406:0" + } + ], + "id" : 19, + "name" : "SourceUnit", + "src" : "0:433:0" +} From 94ce0462ba77bcf267abe370f0fde12363d01451 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 6 Sep 2019 14:19:49 +0200 Subject: [PATCH 019/283] Add backup extension to all sed commands in the command line tests for OSX sed. --- test/cmdlineTests.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index 7cd25229775d..068f02d4c2c8 100755 --- a/test/cmdlineTests.sh +++ b/test/cmdlineTests.sh @@ -143,9 +143,9 @@ function test_solc_behaviour() if [[ "$solc_args" == *"--standard-json"* ]] then - sed -i -e 's/{[^{]*Warning: This is a pre-release compiler version[^}]*},\{0,1\}//' "$stdout_path" + sed -i.bak -e 's/{[^{]*Warning: This is a pre-release compiler version[^}]*},\{0,1\}//' "$stdout_path" sed -i.bak -E -e 's/ Consider adding \\"pragma solidity \^[0-9.]*;\\"//g' "$stdout_path" - sed -i -e 's/"errors":\[\],\{0,1\}//' "$stdout_path" + sed -i.bak -e 's/"errors":\[\],\{0,1\}//' "$stdout_path" # Remove explicit bytecode and references to bytecode offsets sed -i.bak -E -e 's/\"object\":\"[a-f0-9]+\"/\"object\":\"bytecode removed\"/g' "$stdout_path" sed -i.bak -E -e 's/\"opcodes\":\"[^"]+\"/\"opcodes\":\"opcodes removed\"/g' "$stdout_path" @@ -154,16 +154,18 @@ function test_solc_behaviour() sed -i.bak -E -e 's/\\n/\'$'\n/g' "$stdout_path" rm "$stdout_path.bak" else - sed -i -e '/^Warning: This is a pre-release compiler version, please do not use it in production./d' "$stderr_path" - sed -i -e 's/ Consider adding "pragma .*$//' "$stderr_path" + sed -i.bak -e '/^Warning: This is a pre-release compiler version, please do not use it in production./d' "$stderr_path" + sed -i.bak -e 's/ Consider adding "pragma .*$//' "$stderr_path" # Remove trailing empty lines. Needs a line break to make OSX sed happy. - sed -i -e '1{/^$/d + sed -i.bak -e '1{/^$/d }' "$stderr_path" + rm "$stderr_path.bak" fi # Remove path to cpp file - sed -i -e 's/^\(Exception while assembling:\).*/\1/' "$stderr_path" + sed -i.bak -e 's/^\(Exception while assembling:\).*/\1/' "$stderr_path" # Remove exception class name. - sed -i -e 's/^\(Dynamic exception type:\).*/\1/' "$stderr_path" + sed -i.bak -e 's/^\(Dynamic exception type:\).*/\1/' "$stderr_path" + rm "$stderr_path.bak" if [[ $exitCode -ne "$exit_code_expected" ]] then From f4d990e5be608d0fd4c8da3a6015a3ab8202b2b1 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 6 Sep 2019 12:21:54 +0200 Subject: [PATCH 020/283] Drop constant and payable fields from ABI. --- Changelog.md | 1 + docs/abi-spec.rst | 7 +------ libsolidity/interface/ABI.cpp | 5 ----- test/libsolidity/ABIJson/basic_test.sol | 2 -- test/libsolidity/ABIJson/constructor_abi.sol | 1 - .../ABIJson/empty_name_input_parameter_with_named_one.sol | 2 -- test/libsolidity/ABIJson/empty_name_return_parameters.sol | 2 -- test/libsolidity/ABIJson/events.sol | 2 -- test/libsolidity/ABIJson/function_type.sol | 2 -- test/libsolidity/ABIJson/function_type_extended.sol | 2 -- test/libsolidity/ABIJson/global_struct.sol | 4 ---- test/libsolidity/ABIJson/include_fallback_function.sol | 1 - test/libsolidity/ABIJson/inherited.sol | 6 ------ test/libsolidity/ABIJson/library_function.sol | 2 -- test/libsolidity/ABIJson/multiple_methods.sol | 4 ---- test/libsolidity/ABIJson/multiple_methods_order.sol | 4 ---- test/libsolidity/ABIJson/multiple_params.sol | 2 -- test/libsolidity/ABIJson/payabl_fallback_function.sol | 1 - test/libsolidity/ABIJson/payable_constructor_abi.sol | 1 - test/libsolidity/ABIJson/payable_function.sol | 4 ---- test/libsolidity/ABIJson/pure_function.sol | 4 ---- test/libsolidity/ABIJson/return_param_in_abi.sol | 3 --- test/libsolidity/ABIJson/return_structs.sol | 2 -- test/libsolidity/ABIJson/return_structs_with_contracts.sol | 2 -- test/libsolidity/ABIJson/structs_and_arrays.sol | 2 -- test/libsolidity/ABIJson/structs_in_libraries.sol | 2 -- test/libsolidity/ABIJson/view_function.sol | 4 ---- test/libsolidity/StandardCompiler.cpp | 4 ++-- 28 files changed, 4 insertions(+), 74 deletions(-) diff --git a/Changelog.md b/Changelog.md index 84c8dffc284d..eaaa0ad311a5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ ### 0.6.0 (unreleased) Breaking changes: + * ABI: remove the deprecated ``constant`` and ``payable`` fields. * Commandline interface: remove the text-based ast printer (``--ast``). * General: Disallow explicit conversions from external function types to ``address`` and add a member called ``address`` to them as replacement. * Type checker: Resulting type of exponentiation is equal to the type of the base. Also allow signed types for the base. diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index 3a6d077d4060..6f7dc7cfba79 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -454,16 +454,11 @@ A function description is a JSON object with the fields: - ``outputs``: an array of objects similar to ``inputs``, can be omitted if function doesn't return anything; - ``stateMutability``: a string with one of the following values: ``pure`` (:ref:`specified to not read blockchain state `), ``view`` (:ref:`specified to not modify the blockchain state `), ``nonpayable`` (function does not accept Ether) and ``payable`` (function accepts Ether); -- ``payable``: ``true`` if function accepts Ether, ``false`` otherwise; -- ``constant``: ``true`` if function is either ``pure`` or ``view``, ``false`` otherwise. -``type`` can be omitted, defaulting to ``"function"``, likewise ``payable`` and ``constant`` can be omitted, both defaulting to ``false``. +``type`` can be omitted, defaulting to ``"function"``. Constructor and fallback function never have ``name`` or ``outputs``. Fallback function doesn't have ``inputs`` either. -.. warning:: - The fields ``constant`` and ``payable`` are deprecated and will be removed in the future. Instead, the ``stateMutability`` field can be used to determine the same properties. - .. note:: Sending non-zero Ether to non-payable function will revert the transaction. diff --git a/libsolidity/interface/ABI.cpp b/libsolidity/interface/ABI.cpp index a21053d9fd98..8ce6dab55320 100644 --- a/libsolidity/interface/ABI.cpp +++ b/libsolidity/interface/ABI.cpp @@ -58,9 +58,6 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) Json::Value method; method["type"] = "function"; method["name"] = it.second->declaration().name(); - // TODO: deprecate constant in a future release - method["constant"] = externalFunctionType->stateMutability() == StateMutability::Pure || it.second->stateMutability() == StateMutability::View; - method["payable"] = externalFunctionType->isPayable(); method["stateMutability"] = stateMutabilityToString(externalFunctionType->stateMutability()); method["inputs"] = formatTypeList( externalFunctionType->parameterNames(), @@ -83,7 +80,6 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) solAssert(!!externalFunctionType, ""); Json::Value method; method["type"] = "constructor"; - method["payable"] = externalFunctionType->isPayable(); method["stateMutability"] = stateMutabilityToString(externalFunctionType->stateMutability()); method["inputs"] = formatTypeList( externalFunctionType->parameterNames(), @@ -99,7 +95,6 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) solAssert(!!externalFunctionType, ""); Json::Value method; method["type"] = "fallback"; - method["payable"] = externalFunctionType->isPayable(); method["stateMutability"] = stateMutabilityToString(externalFunctionType->stateMutability()); abi.emplace(std::move(method)); } diff --git a/test/libsolidity/ABIJson/basic_test.sol b/test/libsolidity/ABIJson/basic_test.sol index ed0b5e715d60..37c833bcfa29 100644 --- a/test/libsolidity/ABIJson/basic_test.sol +++ b/test/libsolidity/ABIJson/basic_test.sol @@ -5,7 +5,6 @@ contract test { // :test // [ // { -// "constant": false, // "inputs": // [ // { @@ -23,7 +22,6 @@ contract test { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/constructor_abi.sol b/test/libsolidity/ABIJson/constructor_abi.sol index 31cc06486d14..d6cb1d49509b 100644 --- a/test/libsolidity/ABIJson/constructor_abi.sol +++ b/test/libsolidity/ABIJson/constructor_abi.sol @@ -23,7 +23,6 @@ contract test { // "type": "bool" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "constructor" // } diff --git a/test/libsolidity/ABIJson/empty_name_input_parameter_with_named_one.sol b/test/libsolidity/ABIJson/empty_name_input_parameter_with_named_one.sol index 6f2baccf71bf..d412e755acff 100644 --- a/test/libsolidity/ABIJson/empty_name_input_parameter_with_named_one.sol +++ b/test/libsolidity/ABIJson/empty_name_input_parameter_with_named_one.sol @@ -9,7 +9,6 @@ contract test { // :test // [ // { -// "constant": false, // "inputs": // [ // { @@ -37,7 +36,6 @@ contract test { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/empty_name_return_parameters.sol b/test/libsolidity/ABIJson/empty_name_return_parameters.sol index 9b287ba5102e..1415276fdce9 100644 --- a/test/libsolidity/ABIJson/empty_name_return_parameters.sol +++ b/test/libsolidity/ABIJson/empty_name_return_parameters.sol @@ -7,7 +7,6 @@ contract test { // :test // [ // { -// "constant": false, // "inputs": // [ // { @@ -25,7 +24,6 @@ contract test { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/events.sol b/test/libsolidity/ABIJson/events.sol index 1988e094b995..bab6a743652e 100644 --- a/test/libsolidity/ABIJson/events.sol +++ b/test/libsolidity/ABIJson/events.sol @@ -55,7 +55,6 @@ contract test { // "type": "event" // }, // { -// "constant": false, // "inputs": // [ // { @@ -73,7 +72,6 @@ contract test { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/function_type.sol b/test/libsolidity/ABIJson/function_type.sol index 182469af086a..51e36b92b5da 100644 --- a/test/libsolidity/ABIJson/function_type.sol +++ b/test/libsolidity/ABIJson/function_type.sol @@ -5,7 +5,6 @@ contract test { // :test // [ // { -// "constant": false, // "inputs": // [ // { @@ -16,7 +15,6 @@ contract test { // ], // "name": "g", // "outputs": [], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/function_type_extended.sol b/test/libsolidity/ABIJson/function_type_extended.sol index 959b35c8a7c5..6257bb4c47ed 100644 --- a/test/libsolidity/ABIJson/function_type_extended.sol +++ b/test/libsolidity/ABIJson/function_type_extended.sol @@ -5,7 +5,6 @@ contract test { // :test // [ // { -// "constant": false, // "inputs": // [ // { @@ -16,7 +15,6 @@ contract test { // ], // "name": "g", // "outputs": [], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/global_struct.sol b/test/libsolidity/ABIJson/global_struct.sol index 71ce17c40b52..baffe7cc498b 100644 --- a/test/libsolidity/ABIJson/global_struct.sol +++ b/test/libsolidity/ABIJson/global_struct.sol @@ -8,7 +8,6 @@ contract C { // :C // [ // { -// "constant": true, // "inputs": // [ // { @@ -27,12 +26,10 @@ contract C { // ], // "name": "f", // "outputs": [], -// "payable": false, // "stateMutability": "view", // "type": "function" // }, // { -// "constant": true, // "inputs": // [ // { @@ -51,7 +48,6 @@ contract C { // ], // "name": "g", // "outputs": [], -// "payable": false, // "stateMutability": "view", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/include_fallback_function.sol b/test/libsolidity/ABIJson/include_fallback_function.sol index f4877ff8bb96..30c1bf39e4a5 100644 --- a/test/libsolidity/ABIJson/include_fallback_function.sol +++ b/test/libsolidity/ABIJson/include_fallback_function.sol @@ -5,7 +5,6 @@ contract test { // :test // [ // { -// "payable": false, // "stateMutability": "nonpayable", // "type": "fallback" // } diff --git a/test/libsolidity/ABIJson/inherited.sol b/test/libsolidity/ABIJson/inherited.sol index 00abd50ef58b..cdd8296d8efc 100644 --- a/test/libsolidity/ABIJson/inherited.sol +++ b/test/libsolidity/ABIJson/inherited.sol @@ -24,7 +24,6 @@ contract Derived is Base { // "type": "event" // }, // { -// "constant": false, // "inputs": // [ // { @@ -42,7 +41,6 @@ contract Derived is Base { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } @@ -80,7 +78,6 @@ contract Derived is Base { // "type": "event" // }, // { -// "constant": false, // "inputs": // [ // { @@ -98,12 +95,10 @@ contract Derived is Base { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // }, // { -// "constant": false, // "inputs": // [ // { @@ -121,7 +116,6 @@ contract Derived is Base { // "type": "bytes32" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/library_function.sol b/test/libsolidity/ABIJson/library_function.sol index 2aad8e164dfb..37efe24ed344 100644 --- a/test/libsolidity/ABIJson/library_function.sol +++ b/test/libsolidity/ABIJson/library_function.sol @@ -7,7 +7,6 @@ library test { // :test // [ // { -// "constant": true, // "inputs": // [ // { @@ -30,7 +29,6 @@ library test { // "type": "uint256[]" // } // ], -// "payable": false, // "stateMutability": "pure", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/multiple_methods.sol b/test/libsolidity/ABIJson/multiple_methods.sol index f3c5dbcfb4db..f4738e6ea16e 100644 --- a/test/libsolidity/ABIJson/multiple_methods.sol +++ b/test/libsolidity/ABIJson/multiple_methods.sol @@ -6,7 +6,6 @@ contract test { // :test // [ // { -// "constant": false, // "inputs": // [ // { @@ -24,12 +23,10 @@ contract test { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // }, // { -// "constant": false, // "inputs": // [ // { @@ -47,7 +44,6 @@ contract test { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/multiple_methods_order.sol b/test/libsolidity/ABIJson/multiple_methods_order.sol index 18ba5e6d45c5..606c80db3ce6 100644 --- a/test/libsolidity/ABIJson/multiple_methods_order.sol +++ b/test/libsolidity/ABIJson/multiple_methods_order.sol @@ -7,7 +7,6 @@ contract test { // :test // [ // { -// "constant": false, // "inputs": // [ // { @@ -25,12 +24,10 @@ contract test { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // }, // { -// "constant": false, // "inputs": // [ // { @@ -48,7 +45,6 @@ contract test { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/multiple_params.sol b/test/libsolidity/ABIJson/multiple_params.sol index 6a53830a3feb..e223fc3eb590 100644 --- a/test/libsolidity/ABIJson/multiple_params.sol +++ b/test/libsolidity/ABIJson/multiple_params.sol @@ -5,7 +5,6 @@ contract test { // :test // [ // { -// "constant": false, // "inputs": // [ // { @@ -28,7 +27,6 @@ contract test { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/payabl_fallback_function.sol b/test/libsolidity/ABIJson/payabl_fallback_function.sol index a92646a2f3f2..938a74a8c690 100644 --- a/test/libsolidity/ABIJson/payabl_fallback_function.sol +++ b/test/libsolidity/ABIJson/payabl_fallback_function.sol @@ -5,7 +5,6 @@ contract test { // :test // [ // { -// "payable": true, // "stateMutability": "payable", // "type": "fallback" // } diff --git a/test/libsolidity/ABIJson/payable_constructor_abi.sol b/test/libsolidity/ABIJson/payable_constructor_abi.sol index efffc28d2e03..e9497b248e96 100644 --- a/test/libsolidity/ABIJson/payable_constructor_abi.sol +++ b/test/libsolidity/ABIJson/payable_constructor_abi.sol @@ -23,7 +23,6 @@ contract test { // "type": "bool" // } // ], -// "payable": true, // "stateMutability": "payable", // "type": "constructor" // } diff --git a/test/libsolidity/ABIJson/payable_function.sol b/test/libsolidity/ABIJson/payable_function.sol index 4ed1e02b3bf5..e9d7dbe4147b 100644 --- a/test/libsolidity/ABIJson/payable_function.sol +++ b/test/libsolidity/ABIJson/payable_function.sol @@ -6,20 +6,16 @@ contract test { // :test // [ // { -// "constant": false, // "inputs": [], // "name": "f", // "outputs": [], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // }, // { -// "constant": false, // "inputs": [], // "name": "g", // "outputs": [], -// "payable": true, // "stateMutability": "payable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/pure_function.sol b/test/libsolidity/ABIJson/pure_function.sol index 072b8f1f9627..c98431eb2a4e 100644 --- a/test/libsolidity/ABIJson/pure_function.sol +++ b/test/libsolidity/ABIJson/pure_function.sol @@ -6,7 +6,6 @@ contract test { // :test // [ // { -// "constant": true, // "inputs": // [ // { @@ -24,12 +23,10 @@ contract test { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "pure", // "type": "function" // }, // { -// "constant": false, // "inputs": // [ // { @@ -52,7 +49,6 @@ contract test { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/return_param_in_abi.sol b/test/libsolidity/ABIJson/return_param_in_abi.sol index 2618e9ed25fa..92782a73d45a 100644 --- a/test/libsolidity/ABIJson/return_param_in_abi.sol +++ b/test/libsolidity/ABIJson/return_param_in_abi.sol @@ -19,12 +19,10 @@ contract test { // "type": "uint8" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "constructor" // }, // { -// "constant": false, // "inputs": [], // "name": "ret", // "outputs": @@ -35,7 +33,6 @@ contract test { // "type": "uint8" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/return_structs.sol b/test/libsolidity/ABIJson/return_structs.sol index 07899389e486..818eb2bbb7ef 100644 --- a/test/libsolidity/ABIJson/return_structs.sol +++ b/test/libsolidity/ABIJson/return_structs.sol @@ -9,7 +9,6 @@ contract C { // :C // [ // { -// "constant": false, // "inputs": [], // "name": "f", // "outputs": @@ -46,7 +45,6 @@ contract C { // "type": "tuple" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/return_structs_with_contracts.sol b/test/libsolidity/ABIJson/return_structs_with_contracts.sol index 46167843a349..12887d5e2354 100644 --- a/test/libsolidity/ABIJson/return_structs_with_contracts.sol +++ b/test/libsolidity/ABIJson/return_structs_with_contracts.sol @@ -8,7 +8,6 @@ contract C { // :C // [ // { -// "constant": false, // "inputs": [], // "name": "f", // "outputs": @@ -37,7 +36,6 @@ contract C { // "type": "address" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/structs_and_arrays.sol b/test/libsolidity/ABIJson/structs_and_arrays.sol index b2b91f7d8266..b2c6bc0ad971 100644 --- a/test/libsolidity/ABIJson/structs_and_arrays.sol +++ b/test/libsolidity/ABIJson/structs_and_arrays.sol @@ -6,7 +6,6 @@ contract test { // :test // [ // { -// "constant": false, // "inputs": // [ // { @@ -27,7 +26,6 @@ contract test { // ], // "name": "f", // "outputs": [], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/structs_in_libraries.sol b/test/libsolidity/ABIJson/structs_in_libraries.sol index c5d08430d8a4..cb63d4a8b2b3 100644 --- a/test/libsolidity/ABIJson/structs_in_libraries.sol +++ b/test/libsolidity/ABIJson/structs_in_libraries.sol @@ -9,7 +9,6 @@ library L { // :L // [ // { -// "constant": true, // "inputs": // [ // { @@ -46,7 +45,6 @@ library L { // ], // "name": "g", // "outputs": [], -// "payable": false, // "stateMutability": "view", // "type": "function" // } diff --git a/test/libsolidity/ABIJson/view_function.sol b/test/libsolidity/ABIJson/view_function.sol index 0c55b6e6e17c..d5f54ecdeefe 100644 --- a/test/libsolidity/ABIJson/view_function.sol +++ b/test/libsolidity/ABIJson/view_function.sol @@ -6,7 +6,6 @@ contract test { // :test // [ // { -// "constant": true, // "inputs": // [ // { @@ -24,12 +23,10 @@ contract test { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "view", // "type": "function" // }, // { -// "constant": false, // "inputs": // [ // { @@ -52,7 +49,6 @@ contract test { // "type": "uint256" // } // ], -// "payable": false, // "stateMutability": "nonpayable", // "type": "function" // } diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index e9d8613a43cd..336455fd2046 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -615,7 +615,7 @@ BOOST_AUTO_TEST_CASE(output_selection_dependent_contract) Json::Value contract = getContractResult(result, "fileA", "A"); BOOST_CHECK(contract.isObject()); BOOST_CHECK(contract["abi"].isArray()); - BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["abi"]), "[{\"constant\":false,\"inputs\":[],\"name\":\"f\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"); + BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["abi"]), "[{\"inputs\":[],\"name\":\"f\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"); } BOOST_AUTO_TEST_CASE(output_selection_dependent_contract_with_import) @@ -647,7 +647,7 @@ BOOST_AUTO_TEST_CASE(output_selection_dependent_contract_with_import) Json::Value contract = getContractResult(result, "fileA", "A"); BOOST_CHECK(contract.isObject()); BOOST_CHECK(contract["abi"].isArray()); - BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["abi"]), "[{\"constant\":false,\"inputs\":[],\"name\":\"f\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"); + BOOST_CHECK_EQUAL(dev::jsonCompactPrint(contract["abi"]), "[{\"inputs\":[],\"name\":\"f\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"); } BOOST_AUTO_TEST_CASE(filename_with_colon) From 793b1890e84d1cf85e5f31b63350011e41ad839c Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 6 Sep 2019 15:35:01 +0200 Subject: [PATCH 021/283] ``type`` field in ABI JSON no longer defaults to ``function`` --- Changelog.md | 1 + docs/abi-spec.rst | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index eaaa0ad311a5..deaab332dd61 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,7 @@ Breaking changes: * ABI: remove the deprecated ``constant`` and ``payable`` fields. + * ABI: the ``type`` field is now required and no longer specified to default to ``function``. * Commandline interface: remove the text-based ast printer (``--ast``). * General: Disallow explicit conversions from external function types to ``address`` and add a member called ``address`` to them as replacement. * Type checker: Resulting type of exponentiation is equal to the type of the base. Also allow signed types for the base. diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index 6f7dc7cfba79..1cd751eee7b2 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -455,8 +455,6 @@ A function description is a JSON object with the fields: - ``outputs``: an array of objects similar to ``inputs``, can be omitted if function doesn't return anything; - ``stateMutability``: a string with one of the following values: ``pure`` (:ref:`specified to not read blockchain state `), ``view`` (:ref:`specified to not modify the blockchain state `), ``nonpayable`` (function does not accept Ether) and ``payable`` (function accepts Ether); -``type`` can be omitted, defaulting to ``"function"``. - Constructor and fallback function never have ``name`` or ``outputs``. Fallback function doesn't have ``inputs`` either. .. note:: From 6f3341a2047b3b0c806340df057254b0743e3579 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 6 Sep 2019 15:29:51 +0200 Subject: [PATCH 022/283] Allow underscores in hex strings. --- Changelog.md | 1 + docs/types/value-types.rst | 2 +- liblangutil/Scanner.cpp | 20 +++++++++++++++---- .../literals/hex_string_with_underscore.sol | 7 +++++++ .../hex_string_duplicate_underscore.sol | 7 +++++++ .../hex_string_leading_underscore.sol | 7 +++++++ .../hex_string_misaligned_underscore.sol | 7 +++++++ .../hex_string_trailing_underscore.sol | 7 +++++++ .../literals/hex_string_underscores_valid.sol | 3 +++ 9 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 test/libsolidity/semanticTests/literals/hex_string_with_underscore.sol create mode 100644 test/libsolidity/syntaxTests/literals/hex_string_duplicate_underscore.sol create mode 100644 test/libsolidity/syntaxTests/literals/hex_string_leading_underscore.sol create mode 100644 test/libsolidity/syntaxTests/literals/hex_string_misaligned_underscore.sol create mode 100644 test/libsolidity/syntaxTests/literals/hex_string_trailing_underscore.sol create mode 100644 test/libsolidity/syntaxTests/literals/hex_string_underscores_valid.sol diff --git a/Changelog.md b/Changelog.md index 224a8331c755..246bd074e78f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Breaking changes: Language Features: * Allow global enums and structs. + * Allow underscores as delimiters in hex strings. Compiler Features: diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index d03a4c55f174..68782027dbfb 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -499,7 +499,7 @@ terminate the string literal. Newline only terminates the string literal if it i Hexadecimal Literals -------------------- -Hexadecimal literals are prefixed with the keyword ``hex`` and are enclosed in double or single-quotes (``hex"001122FF"``). Their content must be a hexadecimal string and their value will be the binary representation of those values. +Hexadecimal literals are prefixed with the keyword ``hex`` and are enclosed in double or single-quotes (``hex"001122FF"``, ``hex'0011_22_FF'``). Their content must be hexadecimal digits which can optionally use a single underscore as separator between byte boundaries. The value of the literal will be the binary representation of the hexadecimal sequence. Hexadecimal literals behave like :ref:`string literals ` and have the same convertibility restrictions. diff --git a/liblangutil/Scanner.cpp b/liblangutil/Scanner.cpp index a317c79b60c5..82b19d8cf87b 100644 --- a/liblangutil/Scanner.cpp +++ b/liblangutil/Scanner.cpp @@ -67,7 +67,7 @@ string langutil::to_string(ScannerError _errorCode) { case ScannerError::NoError: return "No error."; case ScannerError::IllegalToken: return "Invalid token."; - case ScannerError::IllegalHexString: return "Expected even number of hex-nibbles within double-quotes."; + case ScannerError::IllegalHexString: return "Expected even number of hex-nibbles."; case ScannerError::IllegalHexDigit: return "Hexadecimal digit missing or invalid."; case ScannerError::IllegalCommentTerminator: return "Expected multi-line comment-terminator."; case ScannerError::IllegalEscapeSequence: return "Invalid escape sequence."; @@ -759,13 +759,25 @@ Token Scanner::scanHexString() char const quote = m_char; advance(); // consume quote LiteralScope literal(this, LITERAL_TYPE_STRING); + bool allowUnderscore = false; while (m_char != quote && !isSourcePastEndOfInput()) { char c = m_char; - if (!scanHexByte(c)) - // can only return false if hex-byte is incomplete (only one hex digit instead of two) + + if (scanHexByte(c)) + { + addLiteralChar(c); + allowUnderscore = true; + } + else if (c == '_') + { + advance(); + if (!allowUnderscore || m_char == quote) + return setError(ScannerError::IllegalNumberSeparator); + allowUnderscore = false; + } + else return setError(ScannerError::IllegalHexString); - addLiteralChar(c); } if (m_char != quote) diff --git a/test/libsolidity/semanticTests/literals/hex_string_with_underscore.sol b/test/libsolidity/semanticTests/literals/hex_string_with_underscore.sol new file mode 100644 index 000000000000..db7f70f83bdc --- /dev/null +++ b/test/libsolidity/semanticTests/literals/hex_string_with_underscore.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure returns(bytes memory) { + return hex"12_34_5678_9A"; + } +} +// ---- +// f() -> 32, 5, left(0x123456789A) diff --git a/test/libsolidity/syntaxTests/literals/hex_string_duplicate_underscore.sol b/test/libsolidity/syntaxTests/literals/hex_string_duplicate_underscore.sol new file mode 100644 index 000000000000..822cd826fbb9 --- /dev/null +++ b/test/libsolidity/syntaxTests/literals/hex_string_duplicate_underscore.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure { + hex"12__34"; + } +} +// ---- +// ParserError: (52-60): Invalid use of number separator '_'. diff --git a/test/libsolidity/syntaxTests/literals/hex_string_leading_underscore.sol b/test/libsolidity/syntaxTests/literals/hex_string_leading_underscore.sol new file mode 100644 index 000000000000..320b181b8910 --- /dev/null +++ b/test/libsolidity/syntaxTests/literals/hex_string_leading_underscore.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure { + hex"_1234"; + } +} +// ---- +// ParserError: (52-57): Invalid use of number separator '_'. diff --git a/test/libsolidity/syntaxTests/literals/hex_string_misaligned_underscore.sol b/test/libsolidity/syntaxTests/literals/hex_string_misaligned_underscore.sol new file mode 100644 index 000000000000..d0b945530fa0 --- /dev/null +++ b/test/libsolidity/syntaxTests/literals/hex_string_misaligned_underscore.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure { + hex"1_234"; + } +} +// ---- +// ParserError: (52-56): Expected even number of hex-nibbles. diff --git a/test/libsolidity/syntaxTests/literals/hex_string_trailing_underscore.sol b/test/libsolidity/syntaxTests/literals/hex_string_trailing_underscore.sol new file mode 100644 index 000000000000..c098587ac6dc --- /dev/null +++ b/test/libsolidity/syntaxTests/literals/hex_string_trailing_underscore.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure { + hex"1234_"; + } +} +// ---- +// ParserError: (52-61): Invalid use of number separator '_'. diff --git a/test/libsolidity/syntaxTests/literals/hex_string_underscores_valid.sol b/test/libsolidity/syntaxTests/literals/hex_string_underscores_valid.sol new file mode 100644 index 000000000000..64ece5a4081b --- /dev/null +++ b/test/libsolidity/syntaxTests/literals/hex_string_underscores_valid.sol @@ -0,0 +1,3 @@ +contract C { + bytes constant c = hex"12_3456_789012"; +} From 59955bed5d5c3a4f4635a430b4402cf756fa1b8f Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Mon, 9 Sep 2019 12:49:54 +0200 Subject: [PATCH 023/283] Adds reserved keyword `virtual`, and adjusting affected tests/docs respectively. --- Changelog.md | 1 + docs/060-breaking-changes.rst | 2 ++ docs/miscellaneous.rst | 2 +- liblangutil/Token.h | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 9f56930ff98c..2b102292667f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Breaking changes: * ABI: the ``type`` field is now required and no longer specified to default to ``function``. * Commandline interface: remove the text-based ast printer (``--ast``). * General: Disallow explicit conversions from external function types to ``address`` and add a member called ``address`` to them as replacement. + * General: New reserved keywords: ``virtual``. * Type checker: Resulting type of exponentiation is equal to the type of the base. Also allow signed types for the base. * Command line interface: Switch to the new error reporter by default. ``--old-reporter`` falls back to the deprecated old error reporter. diff --git a/docs/060-breaking-changes.rst b/docs/060-breaking-changes.rst index 6c80cc2a7e1c..173c05901bf0 100644 --- a/docs/060-breaking-changes.rst +++ b/docs/060-breaking-changes.rst @@ -17,6 +17,8 @@ This section lists purely syntactic changes that do not affect the behavior of e * Conversions from external function types to ``address`` are now disallowed. Instead external function types have a member called ``address``, similar to the existing ``selector`` member. +* New reserved keywords: ``virtual``. + Semantic Only Changes ===================== diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst index 137513b830ea..0111fa4a19ed 100644 --- a/docs/miscellaneous.rst +++ b/docs/miscellaneous.rst @@ -450,7 +450,7 @@ These keywords are reserved in Solidity. They might become part of the syntax in ``define``, ``final``, ``immutable``, ``implements``, ``in``, ``inline``, ``let``, ``macro``, ``match``, ``mutable``, ``null``, ``of``, ``override``, ``partial``, ``promise``, ``reference``, ``relocatable``, ``sealed``, ``sizeof``, ``static``, ``supports``, ``switch``, ``try``, ``typedef``, ``typeof``, -``unchecked``. +``unchecked``, ``virtual``. Language Grammar ================ diff --git a/liblangutil/Token.h b/liblangutil/Token.h index c725c43bded3..9bac424b76ca 100644 --- a/liblangutil/Token.h +++ b/liblangutil/Token.h @@ -262,6 +262,7 @@ namespace langutil K(Typedef, "typedef", 0) \ K(TypeOf, "typeof", 0) \ K(Unchecked, "unchecked", 0) \ + K(Virtual, "virtual", 0) \ \ /* Illegal token - not able to scan. */ \ T(Illegal, "ILLEGAL", 0) \ @@ -310,7 +311,7 @@ namespace TokenTraits constexpr bool isEtherSubdenomination(Token op) { return op == Token::SubWei || op == Token::SubSzabo || op == Token::SubFinney || op == Token::SubEther; } constexpr bool isTimeSubdenomination(Token op) { return op == Token::SubSecond || op == Token::SubMinute || op == Token::SubHour || op == Token::SubDay || op == Token::SubWeek || op == Token::SubYear; } - constexpr bool isReservedKeyword(Token op) { return (Token::Abstract <= op && op <= Token::Unchecked); } + constexpr bool isReservedKeyword(Token op) { return (Token::Abstract <= op && op <= Token::Virtual); } inline Token AssignmentToBinaryOp(Token op) { From 5cfe0b7670528aacce499bedaf2228074bc075fc Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Wed, 4 Sep 2019 17:45:12 +0200 Subject: [PATCH 024/283] Allow explicit conversion from address to address payable --- Changelog.md | 1 + docs/060-breaking-changes.rst | 2 + docs/types/conversion.rst | 2 + docs/types/value-types.rst | 18 +++--- libsolidity/analysis/TypeChecker.cpp | 15 +++-- libsolidity/ast/AST.h | 15 +++-- libsolidity/ast/ASTJsonConverter.cpp | 2 +- libsolidity/ast/TypeProvider.cpp | 9 ++- libsolidity/ast/TypeProvider.h | 2 +- libsolidity/ast/Types.cpp | 4 +- libsolidity/parsing/Parser.cpp | 25 +++++++-- test/libsolidity/ASTJSON/address_payable.json | 56 +++++++++---------- .../ASTJSON/address_payable_legacy.json | 54 +++++++++--------- .../ASTJSON/long_type_name_identifier.json | 32 +++++------ .../long_type_name_identifier_legacy.json | 32 +++++------ test/libsolidity/ASTJSON/short_type_name.json | 28 +++++----- .../ASTJSON/short_type_name_legacy.json | 28 +++++----- .../ASTJSON/short_type_name_ref.json | 30 +++++----- .../ASTJSON/short_type_name_ref_legacy.json | 30 +++++----- ...explicit_conversion_address_to_payable.sol | 11 ++++ .../explicit_conversion_sender_to_payable.sol | 9 +++ .../explicit_conversion_this_to_payable.sol | 8 +++ .../parsing/payable_without_arguments.sol | 7 +++ 23 files changed, 248 insertions(+), 172 deletions(-) create mode 100644 test/libsolidity/syntaxTests/conversion/explicit_conversion_address_to_payable.sol create mode 100644 test/libsolidity/syntaxTests/conversion/explicit_conversion_sender_to_payable.sol create mode 100644 test/libsolidity/syntaxTests/conversion/explicit_conversion_this_to_payable.sol create mode 100644 test/libsolidity/syntaxTests/parsing/payable_without_arguments.sol diff --git a/Changelog.md b/Changelog.md index 2b102292667f..0817154ccd8b 100644 --- a/Changelog.md +++ b/Changelog.md @@ -13,6 +13,7 @@ Breaking changes: Language Features: * Allow global enums and structs. * Allow underscores as delimiters in hex strings. + * Allow explicit conversions from ``address`` to ``address payable`` via ``payable(...)``. Compiler Features: diff --git a/docs/060-breaking-changes.rst b/docs/060-breaking-changes.rst index 173c05901bf0..79cc268deafa 100644 --- a/docs/060-breaking-changes.rst +++ b/docs/060-breaking-changes.rst @@ -16,6 +16,8 @@ This section lists purely syntactic changes that do not affect the behavior of e * Conversions from external function types to ``address`` are now disallowed. Instead external function types have a member called ``address``, similar to the existing ``selector`` member. +* Conversions from ``address`` to ``address payable`` are now possible via ``payable(x)``, where + ``x`` must be of type ``address``. * New reserved keywords: ``virtual``. diff --git a/docs/types/conversion.rst b/docs/types/conversion.rst index 51e37340525c..b2bf088bd2eb 100644 --- a/docs/types/conversion.rst +++ b/docs/types/conversion.rst @@ -128,3 +128,5 @@ As described in :ref:`address_literals`, hex literals of the correct size that p test are of ``address`` type. No other literals can be implicitly converted to the ``address`` type. Explicit conversions from ``bytes20`` or any integer type to ``address`` result in ``address payable``. + +An ``address a`` can be converted to ``address payable`` via ``payable(a)``. diff --git a/docs/types/value-types.rst b/docs/types/value-types.rst index 68782027dbfb..f8c461c7351c 100644 --- a/docs/types/value-types.rst +++ b/docs/types/value-types.rst @@ -171,18 +171,20 @@ while a plain ``address`` cannot be sent Ether. Type conversions: -Implicit conversions from ``address payable`` to ``address`` are allowed, whereas conversions from ``address`` to ``address payable`` are -not possible (the only way to perform such a conversion is by using an intermediate conversion to ``uint160``). +Implicit conversions from ``address payable`` to ``address`` are allowed, whereas conversions from ``address`` to ``address payable`` +must be explicit via ``payable(
)``. :ref:`Address literals` can be implicitly converted to ``address payable``. Explicit conversions to and from ``address`` are allowed for integers, integer literals, ``bytes20`` and contract types with the following caveat: -Conversions of the form ``address payable(x)`` are not allowed. Instead the result of a conversion of the form ``address(x)`` +The result of a conversion of the form ``address(x)`` has the type ``address payable``, if ``x`` is of integer or fixed bytes type, a literal or a contract with a payable fallback function. If ``x`` is a contract without payable fallback function, then ``address(x)`` will be of type ``address``. In external function signatures ``address`` is used for both the ``address`` and the ``address payable`` type. +Only expressions of type ``address`` can be converted to type ``address payable`` via ``payable(
)``. + .. note:: It might very well be that you do not need to care about the distinction between ``address`` and ``address payable`` and just use ``address`` everywhere. For example, @@ -310,10 +312,12 @@ Every :ref:`contract` defines its own type. You can implicitly convert contracts to contracts they inherit from. Contracts can be explicitly converted to and from the ``address`` type. -Explicit conversion to and from the ``address payable`` type -is only possible if the contract type has a payable fallback function. -The conversion is still performed using ``address(x)`` and not -using ``address payable(x)``. You can find more information in the section about +Explicit conversion to and from the ``address payable`` type is only possible +if the contract type has a payable fallback function. The conversion is still +performed using ``address(x)``. If the contract type does not have a payable +fallback function, the conversion to ``address payable`` can be done using +``payable(address(x))``. +You can find more information in the section about the :ref:`address type
`. .. note:: diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index e0f83349346a..d1faa6882c8f 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1527,11 +1527,14 @@ TypePointer TypeChecker::typeCheckTypeConversionAndRetrieveReturnType( "\"." ); } - if (resultType->category() == Type::Category::Address) - { - bool const payable = argType->isExplicitlyConvertibleTo(*TypeProvider::payableAddress()); - resultType = payable ? TypeProvider::payableAddress() : TypeProvider::address(); - } + if (auto addressType = dynamic_cast(resultType)) + if (addressType->stateMutability() != StateMutability::Payable) + { + bool payable = false; + if (argType->category() != Type::Category::Address) + payable = argType->isExplicitlyConvertibleTo(*TypeProvider::payableAddress()); + resultType = payable ? TypeProvider::payableAddress() : TypeProvider::address(); + } } return resultType; } @@ -2423,7 +2426,7 @@ bool TypeChecker::visit(Identifier const& _identifier) void TypeChecker::endVisit(ElementaryTypeNameExpression const& _expr) { - _expr.annotation().type = TypeProvider::typeType(TypeProvider::fromElementaryTypeName(_expr.typeName())); + _expr.annotation().type = TypeProvider::typeType(TypeProvider::fromElementaryTypeName(_expr.type().typeName(), _expr.type().stateMutability())); _expr.annotation().isPure = true; } diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 764a5d9fe5f6..e808003ec90e 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -1682,16 +1682,21 @@ class Identifier: public PrimaryExpression class ElementaryTypeNameExpression: public PrimaryExpression { public: - ElementaryTypeNameExpression(SourceLocation const& _location, ElementaryTypeNameToken const& _type): - PrimaryExpression(_location), m_typeToken(_type) - {} + ElementaryTypeNameExpression( + SourceLocation const& _location, + ASTPointer const& _type + ): + PrimaryExpression(_location), + m_type(_type) + { + } void accept(ASTVisitor& _visitor) override; void accept(ASTConstVisitor& _visitor) const override; - ElementaryTypeNameToken const& typeName() const { return m_typeToken; } + ElementaryTypeName const& type() const { return *m_type; } private: - ElementaryTypeNameToken m_typeToken; + ASTPointer m_type; }; /** diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index a81ec3ac95c1..c6f7ecf9b4c7 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -712,7 +712,7 @@ bool ASTJsonConverter::visit(Identifier const& _node) bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node) { std::vector> attributes = { - make_pair(m_legacy ? "value" : "typeName", _node.typeName().toString()) + make_pair(m_legacy ? "value" : "typeName", _node.type().typeName().toString()) }; appendExpressionAttributes(attributes, _node.annotation()); setJsonNode(_node, "ElementaryTypeNameExpression", std::move(attributes)); diff --git a/libsolidity/ast/TypeProvider.cpp b/libsolidity/ast/TypeProvider.cpp index 6e94c011be3b..7d7824da3fb3 100644 --- a/libsolidity/ast/TypeProvider.cpp +++ b/libsolidity/ast/TypeProvider.cpp @@ -200,7 +200,7 @@ inline T const* TypeProvider::createAndGet(Args&& ... _args) return static_cast(instance().m_generalTypes.back().get()); } -Type const* TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken const& _type) +Type const* TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken const& _type, boost::optional _stateMutability) { solAssert( TokenTraits::isElementaryTypeName(_type.token()), @@ -233,7 +233,14 @@ Type const* TypeProvider::fromElementaryTypeName(ElementaryTypeNameToken const& case Token::UFixed: return fixedPoint(128, 18, FixedPointType::Modifier::Unsigned); case Token::Address: + { + if (_stateMutability) + { + solAssert(*_stateMutability == StateMutability::Payable, ""); + return payableAddress(); + } return address(); + } case Token::Bool: return boolean(); case Token::Bytes: diff --git a/libsolidity/ast/TypeProvider.h b/libsolidity/ast/TypeProvider.h index 4b18f52e6b3f..f6f4e1f7430d 100644 --- a/libsolidity/ast/TypeProvider.h +++ b/libsolidity/ast/TypeProvider.h @@ -54,7 +54,7 @@ class TypeProvider /// @name Factory functions /// Factory functions that convert an AST @ref TypeName to a Type. - static Type const* fromElementaryTypeName(ElementaryTypeNameToken const& _type); + static Type const* fromElementaryTypeName(ElementaryTypeNameToken const& _type, boost::optional _stateMutability = {}); /// Converts a given elementary type name with optional data location /// suffix " storage", " calldata" or " memory" to a type pointer. If suffix not given, defaults to " storage". diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 30323c3160e4..79d41bfe9265 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -412,7 +412,9 @@ BoolResult AddressType::isImplicitlyConvertibleTo(Type const& _other) const BoolResult AddressType::isExplicitlyConvertibleTo(Type const& _convertTo) const { - if (auto const* contractType = dynamic_cast(&_convertTo)) + if (_convertTo.category() == category()) + return true; + else if (auto const* contractType = dynamic_cast(&_convertTo)) return (m_stateMutability >= StateMutability::Payable) || !contractType->isPayable(); return isImplicitlyConvertibleTo(_convertTo) || _convertTo.category() == Category::Integer || diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 1945a07dcdc8..14c4a29fc2a2 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1585,6 +1585,17 @@ ASTPointer Parser::parseLeftHandSideExpression( nodeFactory.markEndPosition(); expression = nodeFactory.createNode(typeName); } + else if (m_scanner->currentToken() == Token::Payable) + { + expectToken(Token::Payable); + nodeFactory.markEndPosition(); + auto expressionType = nodeFactory.createNode( + ElementaryTypeNameToken(Token::Address, 160, 0), + boost::make_optional(StateMutability::Payable) + ); + expression = nodeFactory.createNode(expressionType); + expectToken(Token::LParen, false); + } else expression = parsePrimaryExpression(); @@ -1725,8 +1736,10 @@ ASTPointer Parser::parsePrimaryExpression() unsigned firstSize; unsigned secondSize; tie(firstSize, secondSize) = m_scanner->currentTokenInfo(); - ElementaryTypeNameToken elementaryExpression(m_scanner->currentToken(), firstSize, secondSize); - expression = nodeFactory.createNode(elementaryExpression); + auto expressionType = nodeFactory.createNode( + ElementaryTypeNameToken(m_scanner->currentToken(), firstSize, secondSize) + ); + expression = nodeFactory.createNode(expressionType); m_scanner->next(); } else @@ -1838,8 +1851,10 @@ Parser::IndexAccessedPath Parser::parseIndexAccessedPath() unsigned firstNum; unsigned secondNum; tie(firstNum, secondNum) = m_scanner->currentTokenInfo(); - ElementaryTypeNameToken elemToken(m_scanner->currentToken(), firstNum, secondNum); - iap.path.push_back(ASTNodeFactory(*this).createNode(elemToken)); + auto expressionType = ASTNodeFactory(*this).createNode( + ElementaryTypeNameToken(m_scanner->currentToken(), firstNum, secondNum) + ); + iap.path.push_back(ASTNodeFactory(*this).createNode(expressionType)); m_scanner->next(); } while (m_scanner->currentToken() == Token::LBrack) @@ -1872,7 +1887,7 @@ ASTPointer Parser::typeNameFromIndexAccessStructure(Parser::IndexAcces if (auto typeName = dynamic_cast(_iap.path.front().get())) { solAssert(_iap.path.size() == 1, ""); - type = nodeFactory.createNode(typeName->typeName()); + type = nodeFactory.createNode(typeName->type().typeName()); } else { diff --git a/test/libsolidity/ASTJSON/address_payable.json b/test/libsolidity/ASTJSON/address_payable.json index 88ce272dc705..834fb1cc92b9 100644 --- a/test/libsolidity/ASTJSON/address_payable.json +++ b/test/libsolidity/ASTJSON/address_payable.json @@ -4,10 +4,10 @@ { "C" : [ - 37 + 39 ] }, - "id" : 38, + "id" : 40, "nodeType" : "SourceUnit", "nodes" : [ @@ -17,10 +17,10 @@ "contractKind" : "contract", "documentation" : null, "fullyImplemented" : true, - "id" : 37, + "id" : 39, "linearizedBaseContracts" : [ - 37 + 39 ], "name" : "C", "nodeType" : "ContractDefinition", @@ -32,7 +32,7 @@ "name" : "m", "nodeType" : "VariableDeclaration", "overrides" : null, - "scope" : 37, + "scope" : 39, "src" : "17:44:1", "stateVariable" : true, "storageLocation" : "default", @@ -83,7 +83,7 @@ { "body" : { - "id" : 35, + "id" : 37, "nodeType" : "Block", "src" : "134:122:1", "statements" : @@ -101,7 +101,7 @@ "name" : "a", "nodeType" : "VariableDeclaration", "overrides" : null, - "scope" : 35, + "scope" : 37, "src" : "144:17:1", "stateVariable" : false, "storageLocation" : "default", @@ -242,7 +242,7 @@ "name" : "c", "nodeType" : "VariableDeclaration", "overrides" : null, - "scope" : 35, + "scope" : 37, "src" : "197:9:1", "stateVariable" : false, "storageLocation" : "default", @@ -268,7 +268,7 @@ "visibility" : "internal" } ], - "id" : 26, + "id" : 27, "initialValue" : { "argumentTypes" : null, @@ -276,15 +276,15 @@ [ { "argumentTypes" : null, - "id" : 24, + "id" : 25, "name" : "this", "nodeType" : "Identifier", "overloadedDeclarations" : [], - "referencedDeclaration" : 66, + "referencedDeclaration" : 68, "src" : "217:4:1", "typeDescriptions" : { - "typeIdentifier" : "t_contract$_C_$37", + "typeIdentifier" : "t_contract$_C_$39", "typeString" : "contract C" } } @@ -294,11 +294,11 @@ "argumentTypes" : [ { - "typeIdentifier" : "t_contract$_C_$37", + "typeIdentifier" : "t_contract$_C_$39", "typeString" : "contract C" } ], - "id" : 23, + "id" : 24, "isConstant" : false, "isLValue" : false, "isPure" : true, @@ -312,7 +312,7 @@ }, "typeName" : "address" }, - "id" : 25, + "id" : 26, "isConstant" : false, "isLValue" : false, "isPure" : false, @@ -334,7 +334,7 @@ "expression" : { "argumentTypes" : null, - "id" : 33, + "id" : 35, "isConstant" : false, "isLValue" : false, "isPure" : false, @@ -345,7 +345,7 @@ "baseExpression" : { "argumentTypes" : null, - "id" : 27, + "id" : 28, "name" : "m", "nodeType" : "Identifier", "overloadedDeclarations" : [], @@ -357,11 +357,11 @@ "typeString" : "mapping(address => address payable)" } }, - "id" : 29, + "id" : 30, "indexExpression" : { "argumentTypes" : null, - "id" : 28, + "id" : 29, "name" : "c", "nodeType" : "Identifier", "overloadedDeclarations" : [], @@ -395,7 +395,7 @@ { "argumentTypes" : null, "hexValue" : "30", - "id" : 31, + "id" : 33, "isConstant" : false, "isLValue" : false, "isPure" : true, @@ -421,7 +421,7 @@ "typeString" : "int_const 0" } ], - "id" : 30, + "id" : 32, "isConstant" : false, "isLValue" : false, "isPure" : true, @@ -435,7 +435,7 @@ }, "typeName" : "address" }, - "id" : 32, + "id" : 34, "isConstant" : false, "isLValue" : false, "isPure" : true, @@ -457,14 +457,14 @@ "typeString" : "address payable" } }, - "id" : 34, + "id" : 36, "nodeType" : "ExpressionStatement", "src" : "232:17:1" } ] }, "documentation" : null, - "id" : 36, + "id" : 38, "implemented" : true, "kind" : "function", "modifiers" : [], @@ -483,7 +483,7 @@ "name" : "arg", "nodeType" : "VariableDeclaration", "overrides" : null, - "scope" : 36, + "scope" : 38, "src" : "78:19:1", "stateVariable" : false, "storageLocation" : "default", @@ -523,7 +523,7 @@ "name" : "r", "nodeType" : "VariableDeclaration", "overrides" : null, - "scope" : 36, + "scope" : 38, "src" : "115:17:1", "stateVariable" : false, "storageLocation" : "default", @@ -551,14 +551,14 @@ ], "src" : "114:19:1" }, - "scope" : 37, + "scope" : 39, "src" : "67:189:1", "stateMutability" : "nonpayable", "superFunction" : null, "visibility" : "public" } ], - "scope" : 38, + "scope" : 40, "src" : "0:258:1" } ], diff --git a/test/libsolidity/ASTJSON/address_payable_legacy.json b/test/libsolidity/ASTJSON/address_payable_legacy.json index a2758b16bff5..0b10724607b9 100644 --- a/test/libsolidity/ASTJSON/address_payable_legacy.json +++ b/test/libsolidity/ASTJSON/address_payable_legacy.json @@ -6,7 +6,7 @@ { "C" : [ - 37 + 39 ] } }, @@ -28,10 +28,10 @@ "fullyImplemented" : true, "linearizedBaseContracts" : [ - 37 + 39 ], "name" : "C", - "scope" : 38 + "scope" : 40 }, "children" : [ @@ -41,7 +41,7 @@ "constant" : false, "name" : "m", "overrides" : null, - "scope" : 37, + "scope" : 39, "stateVariable" : true, "storageLocation" : "default", "type" : "mapping(address => address payable)", @@ -101,7 +101,7 @@ ], "name" : "f", "overrides" : null, - "scope" : 37, + "scope" : 39, "stateMutability" : "nonpayable", "superFunction" : null, "visibility" : "public" @@ -117,7 +117,7 @@ "constant" : false, "name" : "arg", "overrides" : null, - "scope" : 36, + "scope" : 38, "stateVariable" : false, "storageLocation" : "default", "type" : "address payable", @@ -156,7 +156,7 @@ "constant" : false, "name" : "r", "overrides" : null, - "scope" : 36, + "scope" : 38, "stateVariable" : false, "storageLocation" : "default", "type" : "address payable", @@ -205,7 +205,7 @@ "constant" : false, "name" : "a", "overrides" : null, - "scope" : 35, + "scope" : 37, "stateVariable" : false, "storageLocation" : "default", "type" : "address payable", @@ -358,7 +358,7 @@ "constant" : false, "name" : "c", "overrides" : null, - "scope" : 35, + "scope" : 37, "stateVariable" : false, "storageLocation" : "default", "type" : "address", @@ -407,7 +407,7 @@ "argumentTypes" : [ { - "typeIdentifier" : "t_contract$_C_$37", + "typeIdentifier" : "t_contract$_C_$39", "typeString" : "contract C" } ], @@ -418,7 +418,7 @@ "type" : "type(address)", "value" : "address" }, - "id" : 23, + "id" : 24, "name" : "ElementaryTypeNameExpression", "src" : "209:7:1" }, @@ -430,21 +430,21 @@ [ null ], - "referencedDeclaration" : 66, + "referencedDeclaration" : 68, "type" : "contract C", "value" : "this" }, - "id" : 24, + "id" : 25, "name" : "Identifier", "src" : "217:4:1" } ], - "id" : 25, + "id" : 26, "name" : "FunctionCall", "src" : "209:13:1" } ], - "id" : 26, + "id" : 27, "name" : "VariableDeclarationStatement", "src" : "197:25:1" }, @@ -488,7 +488,7 @@ "type" : "mapping(address => address payable)", "value" : "m" }, - "id" : 27, + "id" : 28, "name" : "Identifier", "src" : "232:1:1" }, @@ -504,12 +504,12 @@ "type" : "address", "value" : "c" }, - "id" : 28, + "id" : 29, "name" : "Identifier", "src" : "234:1:1" } ], - "id" : 29, + "id" : 30, "name" : "IndexAccess", "src" : "232:4:1" }, @@ -548,7 +548,7 @@ "type" : "type(address)", "value" : "address" }, - "id" : 30, + "id" : 32, "name" : "ElementaryTypeNameExpression", "src" : "239:7:1" }, @@ -566,42 +566,42 @@ "type" : "int_const 0", "value" : "0" }, - "id" : 31, + "id" : 33, "name" : "Literal", "src" : "247:1:1" } ], - "id" : 32, + "id" : 34, "name" : "FunctionCall", "src" : "239:10:1" } ], - "id" : 33, + "id" : 35, "name" : "Assignment", "src" : "232:17:1" } ], - "id" : 34, + "id" : 36, "name" : "ExpressionStatement", "src" : "232:17:1" } ], - "id" : 35, + "id" : 37, "name" : "Block", "src" : "134:122:1" } ], - "id" : 36, + "id" : 38, "name" : "FunctionDefinition", "src" : "67:189:1" } ], - "id" : 37, + "id" : 39, "name" : "ContractDefinition", "src" : "0:258:1" } ], - "id" : 38, + "id" : 40, "name" : "SourceUnit", "src" : "0:259:1" } diff --git a/test/libsolidity/ASTJSON/long_type_name_identifier.json b/test/libsolidity/ASTJSON/long_type_name_identifier.json index dc0c6447f0d3..595f5b6412cc 100644 --- a/test/libsolidity/ASTJSON/long_type_name_identifier.json +++ b/test/libsolidity/ASTJSON/long_type_name_identifier.json @@ -4,10 +4,10 @@ { "c" : [ - 14 + 15 ] }, - "id" : 15, + "id" : 16, "nodeType" : "SourceUnit", "nodes" : [ @@ -17,10 +17,10 @@ "contractKind" : "contract", "documentation" : null, "fullyImplemented" : true, - "id" : 14, + "id" : 15, "linearizedBaseContracts" : [ - 14 + 15 ], "name" : "c", "nodeType" : "ContractDefinition", @@ -32,7 +32,7 @@ "name" : "a", "nodeType" : "VariableDeclaration", "overrides" : null, - "scope" : 14, + "scope" : 15, "src" : "13:8:1", "stateVariable" : true, "storageLocation" : "default", @@ -71,7 +71,7 @@ { "body" : { - "id" : 12, + "id" : 13, "nodeType" : "Block", "src" : "43:25:1", "statements" : @@ -79,17 +79,17 @@ { "assignments" : [ - 9 + 10 ], "declarations" : [ { "constant" : false, - "id" : 9, + "id" : 10, "name" : "b", "nodeType" : "VariableDeclaration", "overrides" : null, - "scope" : 12, + "scope" : 13, "src" : "45:16:1", "stateVariable" : false, "storageLocation" : "storage", @@ -102,7 +102,7 @@ { "baseType" : { - "id" : 7, + "id" : 8, "name" : "uint", "nodeType" : "ElementaryTypeName", "src" : "45:4:1", @@ -112,7 +112,7 @@ "typeString" : "uint256" } }, - "id" : 8, + "id" : 9, "length" : null, "nodeType" : "ArrayTypeName", "src" : "45:6:1", @@ -126,11 +126,11 @@ "visibility" : "internal" } ], - "id" : 11, + "id" : 12, "initialValue" : { "argumentTypes" : null, - "id" : 10, + "id" : 11, "name" : "a", "nodeType" : "Identifier", "overloadedDeclarations" : [], @@ -148,7 +148,7 @@ ] }, "documentation" : null, - "id" : 13, + "id" : 14, "implemented" : true, "kind" : "function", "modifiers" : [], @@ -169,14 +169,14 @@ "parameters" : [], "src" : "43:0:1" }, - "scope" : 14, + "scope" : 15, "src" : "23:45:1", "stateMutability" : "nonpayable", "superFunction" : null, "visibility" : "public" } ], - "scope" : 15, + "scope" : 16, "src" : "0:70:1" } ], diff --git a/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json b/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json index 4576770890a0..1f222fe84b5f 100644 --- a/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json +++ b/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json @@ -6,7 +6,7 @@ { "c" : [ - 14 + 15 ] } }, @@ -28,10 +28,10 @@ "fullyImplemented" : true, "linearizedBaseContracts" : [ - 14 + 15 ], "name" : "c", - "scope" : 15 + "scope" : 16 }, "children" : [ @@ -41,7 +41,7 @@ "constant" : false, "name" : "a", "overrides" : null, - "scope" : 14, + "scope" : 15, "stateVariable" : true, "storageLocation" : "default", "type" : "uint256[]", @@ -91,7 +91,7 @@ ], "name" : "f", "overrides" : null, - "scope" : 14, + "scope" : 15, "stateMutability" : "nonpayable", "superFunction" : null, "visibility" : "public" @@ -132,7 +132,7 @@ { "assignments" : [ - 9 + 10 ] }, "children" : @@ -143,7 +143,7 @@ "constant" : false, "name" : "b", "overrides" : null, - "scope" : 12, + "scope" : 13, "stateVariable" : false, "storageLocation" : "storage", "type" : "uint256[]", @@ -166,17 +166,17 @@ "name" : "uint", "type" : "uint256" }, - "id" : 7, + "id" : 8, "name" : "ElementaryTypeName", "src" : "45:4:1" } ], - "id" : 8, + "id" : 9, "name" : "ArrayTypeName", "src" : "45:6:1" } ], - "id" : 9, + "id" : 10, "name" : "VariableDeclaration", "src" : "45:16:1" }, @@ -192,32 +192,32 @@ "type" : "uint256[] storage ref", "value" : "a" }, - "id" : 10, + "id" : 11, "name" : "Identifier", "src" : "64:1:1" } ], - "id" : 11, + "id" : 12, "name" : "VariableDeclarationStatement", "src" : "45:20:1" } ], - "id" : 12, + "id" : 13, "name" : "Block", "src" : "43:25:1" } ], - "id" : 13, + "id" : 14, "name" : "FunctionDefinition", "src" : "23:45:1" } ], - "id" : 14, + "id" : 15, "name" : "ContractDefinition", "src" : "0:70:1" } ], - "id" : 15, + "id" : 16, "name" : "SourceUnit", "src" : "0:71:1" } diff --git a/test/libsolidity/ASTJSON/short_type_name.json b/test/libsolidity/ASTJSON/short_type_name.json index 823d04d3df56..d599be955d67 100644 --- a/test/libsolidity/ASTJSON/short_type_name.json +++ b/test/libsolidity/ASTJSON/short_type_name.json @@ -4,10 +4,10 @@ { "c" : [ - 10 + 11 ] }, - "id" : 11, + "id" : 12, "nodeType" : "SourceUnit", "nodes" : [ @@ -17,10 +17,10 @@ "contractKind" : "contract", "documentation" : null, "fullyImplemented" : true, - "id" : 10, + "id" : 11, "linearizedBaseContracts" : [ - 10 + 11 ], "name" : "c", "nodeType" : "ContractDefinition", @@ -29,7 +29,7 @@ { "body" : { - "id" : 8, + "id" : 9, "nodeType" : "Block", "src" : "33:20:1", "statements" : @@ -37,17 +37,17 @@ { "assignments" : [ - 6 + 7 ], "declarations" : [ { "constant" : false, - "id" : 6, + "id" : 7, "name" : "x", "nodeType" : "VariableDeclaration", "overrides" : null, - "scope" : 8, + "scope" : 9, "src" : "35:15:1", "stateVariable" : false, "storageLocation" : "memory", @@ -60,7 +60,7 @@ { "baseType" : { - "id" : 4, + "id" : 5, "name" : "uint", "nodeType" : "ElementaryTypeName", "src" : "35:4:1", @@ -70,7 +70,7 @@ "typeString" : "uint256" } }, - "id" : 5, + "id" : 6, "length" : null, "nodeType" : "ArrayTypeName", "src" : "35:6:1", @@ -84,7 +84,7 @@ "visibility" : "internal" } ], - "id" : 7, + "id" : 8, "initialValue" : null, "nodeType" : "VariableDeclarationStatement", "src" : "35:15:1" @@ -92,7 +92,7 @@ ] }, "documentation" : null, - "id" : 9, + "id" : 10, "implemented" : true, "kind" : "function", "modifiers" : [], @@ -113,14 +113,14 @@ "parameters" : [], "src" : "33:0:1" }, - "scope" : 10, + "scope" : 11, "src" : "13:40:1", "stateMutability" : "nonpayable", "superFunction" : null, "visibility" : "public" } ], - "scope" : 11, + "scope" : 12, "src" : "0:55:1" } ], diff --git a/test/libsolidity/ASTJSON/short_type_name_legacy.json b/test/libsolidity/ASTJSON/short_type_name_legacy.json index ee4d1fce3ece..92d0abc306ad 100644 --- a/test/libsolidity/ASTJSON/short_type_name_legacy.json +++ b/test/libsolidity/ASTJSON/short_type_name_legacy.json @@ -6,7 +6,7 @@ { "c" : [ - 10 + 11 ] } }, @@ -28,10 +28,10 @@ "fullyImplemented" : true, "linearizedBaseContracts" : [ - 10 + 11 ], "name" : "c", - "scope" : 11 + "scope" : 12 }, "children" : [ @@ -48,7 +48,7 @@ ], "name" : "f", "overrides" : null, - "scope" : 10, + "scope" : 11, "stateMutability" : "nonpayable", "superFunction" : null, "visibility" : "public" @@ -89,7 +89,7 @@ { "assignments" : [ - 6 + 7 ], "initialValue" : null }, @@ -101,7 +101,7 @@ "constant" : false, "name" : "x", "overrides" : null, - "scope" : 8, + "scope" : 9, "stateVariable" : false, "storageLocation" : "memory", "type" : "uint256[]", @@ -124,42 +124,42 @@ "name" : "uint", "type" : "uint256" }, - "id" : 4, + "id" : 5, "name" : "ElementaryTypeName", "src" : "35:4:1" } ], - "id" : 5, + "id" : 6, "name" : "ArrayTypeName", "src" : "35:6:1" } ], - "id" : 6, + "id" : 7, "name" : "VariableDeclaration", "src" : "35:15:1" } ], - "id" : 7, + "id" : 8, "name" : "VariableDeclarationStatement", "src" : "35:15:1" } ], - "id" : 8, + "id" : 9, "name" : "Block", "src" : "33:20:1" } ], - "id" : 9, + "id" : 10, "name" : "FunctionDefinition", "src" : "13:40:1" } ], - "id" : 10, + "id" : 11, "name" : "ContractDefinition", "src" : "0:55:1" } ], - "id" : 11, + "id" : 12, "name" : "SourceUnit", "src" : "0:56:1" } diff --git a/test/libsolidity/ASTJSON/short_type_name_ref.json b/test/libsolidity/ASTJSON/short_type_name_ref.json index 5224f26f2fee..51a13102fa5e 100644 --- a/test/libsolidity/ASTJSON/short_type_name_ref.json +++ b/test/libsolidity/ASTJSON/short_type_name_ref.json @@ -4,10 +4,10 @@ { "c" : [ - 11 + 12 ] }, - "id" : 12, + "id" : 13, "nodeType" : "SourceUnit", "nodes" : [ @@ -17,10 +17,10 @@ "contractKind" : "contract", "documentation" : null, "fullyImplemented" : true, - "id" : 11, + "id" : 12, "linearizedBaseContracts" : [ - 11 + 12 ], "name" : "c", "nodeType" : "ContractDefinition", @@ -29,7 +29,7 @@ { "body" : { - "id" : 9, + "id" : 10, "nodeType" : "Block", "src" : "33:25:1", "statements" : @@ -37,17 +37,17 @@ { "assignments" : [ - 7 + 8 ], "declarations" : [ { "constant" : false, - "id" : 7, + "id" : 8, "name" : "rows", "nodeType" : "VariableDeclaration", "overrides" : null, - "scope" : 9, + "scope" : 10, "src" : "35:20:1", "stateVariable" : false, "storageLocation" : "memory", @@ -62,7 +62,7 @@ { "baseType" : { - "id" : 4, + "id" : 5, "name" : "uint", "nodeType" : "ElementaryTypeName", "src" : "35:4:1", @@ -72,7 +72,7 @@ "typeString" : "uint256" } }, - "id" : 5, + "id" : 6, "length" : null, "nodeType" : "ArrayTypeName", "src" : "35:6:1", @@ -82,7 +82,7 @@ "typeString" : "uint256[]" } }, - "id" : 6, + "id" : 7, "length" : null, "nodeType" : "ArrayTypeName", "src" : "35:8:1", @@ -96,7 +96,7 @@ "visibility" : "internal" } ], - "id" : 8, + "id" : 9, "initialValue" : null, "nodeType" : "VariableDeclarationStatement", "src" : "35:20:1" @@ -104,7 +104,7 @@ ] }, "documentation" : null, - "id" : 10, + "id" : 11, "implemented" : true, "kind" : "function", "modifiers" : [], @@ -125,14 +125,14 @@ "parameters" : [], "src" : "33:0:1" }, - "scope" : 11, + "scope" : 12, "src" : "13:45:1", "stateMutability" : "nonpayable", "superFunction" : null, "visibility" : "public" } ], - "scope" : 12, + "scope" : 13, "src" : "0:60:1" } ], diff --git a/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json b/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json index 0fbecedf8983..99b4d550ebb7 100644 --- a/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json +++ b/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json @@ -6,7 +6,7 @@ { "c" : [ - 11 + 12 ] } }, @@ -28,10 +28,10 @@ "fullyImplemented" : true, "linearizedBaseContracts" : [ - 11 + 12 ], "name" : "c", - "scope" : 12 + "scope" : 13 }, "children" : [ @@ -48,7 +48,7 @@ ], "name" : "f", "overrides" : null, - "scope" : 11, + "scope" : 12, "stateMutability" : "nonpayable", "superFunction" : null, "visibility" : "public" @@ -89,7 +89,7 @@ { "assignments" : [ - 7 + 8 ], "initialValue" : null }, @@ -101,7 +101,7 @@ "constant" : false, "name" : "rows", "overrides" : null, - "scope" : 9, + "scope" : 10, "stateVariable" : false, "storageLocation" : "memory", "type" : "uint256[][]", @@ -132,47 +132,47 @@ "name" : "uint", "type" : "uint256" }, - "id" : 4, + "id" : 5, "name" : "ElementaryTypeName", "src" : "35:4:1" } ], - "id" : 5, + "id" : 6, "name" : "ArrayTypeName", "src" : "35:6:1" } ], - "id" : 6, + "id" : 7, "name" : "ArrayTypeName", "src" : "35:8:1" } ], - "id" : 7, + "id" : 8, "name" : "VariableDeclaration", "src" : "35:20:1" } ], - "id" : 8, + "id" : 9, "name" : "VariableDeclarationStatement", "src" : "35:20:1" } ], - "id" : 9, + "id" : 10, "name" : "Block", "src" : "33:25:1" } ], - "id" : 10, + "id" : 11, "name" : "FunctionDefinition", "src" : "13:45:1" } ], - "id" : 11, + "id" : 12, "name" : "ContractDefinition", "src" : "0:60:1" } ], - "id" : 12, + "id" : 13, "name" : "SourceUnit", "src" : "0:61:1" } diff --git a/test/libsolidity/syntaxTests/conversion/explicit_conversion_address_to_payable.sol b/test/libsolidity/syntaxTests/conversion/explicit_conversion_address_to_payable.sol new file mode 100644 index 000000000000..d44841fd76c7 --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/explicit_conversion_address_to_payable.sol @@ -0,0 +1,11 @@ +contract C { + function g(address payable _p) internal pure returns (uint) { + return 1; + } + function f(address _a) public pure { + uint x = g(payable(_a)); + uint y = g(_a); + } +} +// ---- +// TypeError: (169-171): Invalid type for argument in function call. Invalid implicit conversion from address to address payable requested. diff --git a/test/libsolidity/syntaxTests/conversion/explicit_conversion_sender_to_payable.sol b/test/libsolidity/syntaxTests/conversion/explicit_conversion_sender_to_payable.sol new file mode 100644 index 000000000000..141a125468f1 --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/explicit_conversion_sender_to_payable.sol @@ -0,0 +1,9 @@ +contract C { + function f() public view { + address payable p = payable(msg.sender); + address payable q = payable(address(msg.sender)); + } +} +// ---- +// Warning: (43-60): Unused local variable. +// Warning: (86-103): Unused local variable. diff --git a/test/libsolidity/syntaxTests/conversion/explicit_conversion_this_to_payable.sol b/test/libsolidity/syntaxTests/conversion/explicit_conversion_this_to_payable.sol new file mode 100644 index 000000000000..7f5519cdff0c --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/explicit_conversion_this_to_payable.sol @@ -0,0 +1,8 @@ +contract C { + function f() public pure { + address payable p = payable(this); + address payable q = payable(address(this)); + } +} +// ---- +// TypeError: (63-76): Explicit type conversion not allowed from "contract C" to "address payable". diff --git a/test/libsolidity/syntaxTests/parsing/payable_without_arguments.sol b/test/libsolidity/syntaxTests/parsing/payable_without_arguments.sol new file mode 100644 index 000000000000..b9486f596c8c --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/payable_without_arguments.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure { + address payable q = payable; + } +} +// ---- +// ParserError: (70-71): Expected '(' but got ';' From 4782c800ec6defebd1b44907054e66e463f70c8a Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Tue, 3 Sep 2019 18:30:00 +0200 Subject: [PATCH 025/283] Initial introduction of array slices with partial implementation for dynamic calldata arrays. --- Changelog.md | 1 + docs/grammar.txt | 2 + libsolidity/analysis/TypeChecker.cpp | 70 +++++- libsolidity/analysis/TypeChecker.h | 1 + libsolidity/analysis/ViewPureChecker.cpp | 7 + libsolidity/analysis/ViewPureChecker.h | 1 + libsolidity/ast/AST.h | 26 +++ libsolidity/ast/ASTJsonConverter.cpp | 12 + libsolidity/ast/ASTJsonConverter.h | 1 + libsolidity/ast/ASTVisitor.h | 4 + libsolidity/ast/AST_accept.h | 26 +++ libsolidity/ast/TypeProvider.cpp | 14 ++ libsolidity/ast/TypeProvider.h | 4 + libsolidity/ast/Types.cpp | 24 ++ libsolidity/ast/Types.h | 31 ++- libsolidity/codegen/CompilerUtils.cpp | 11 + libsolidity/codegen/ExpressionCompiler.cpp | 205 ++++++++++++------ libsolidity/codegen/ExpressionCompiler.h | 1 + libsolidity/codegen/YulUtilFunctions.cpp | 5 - .../codegen/ir/IRGeneratorForStatements.cpp | 5 + .../codegen/ir/IRGeneratorForStatements.h | 1 + libsolidity/formal/SMTEncoder.cpp | 9 + libsolidity/formal/SMTEncoder.h | 1 + libsolidity/parsing/Parser.cpp | 55 ++++- libsolidity/parsing/Parser.h | 8 +- .../abiDecodeV1/decode_slice.sol | 9 + .../array/calldata_slice_access.sol | 44 ++++ .../array/slice/bytes_calldata.sol | 5 + .../syntaxTests/array/slice/bytes_memory.sol | 7 + .../syntaxTests/array/slice/bytes_storage.sol | 8 + .../array/slice/calldata_dynamic.sol | 5 + .../array/slice/calldata_dynamic_access.sol | 9 + .../calldata_dynamic_convert_to_memory.sol | 7 + .../array/slice/calldata_dynamic_encode.sol | 7 + .../array/slice/calldata_dynamic_forward.sol | 7 + .../array/slice/calldata_static.sol | 7 + .../array/slice/memory_dynamic.sol | 7 + .../syntaxTests/array/slice/memory_static.sol | 7 + .../syntaxTests/array/slice/slice_literal.sol | 7 + .../array/slice/slice_memory_bytes.sol | 8 + .../array/slice/slice_memory_string.sol | 8 + .../syntaxTests/array/slice/slice_string.sol | 7 + .../array/slice/storage_dynamic.sol | 8 + .../array/slice/storage_static.sol | 8 + .../parsing/array_range_and_ternary.sol | 8 + .../parsing/array_range_conversion.sol | 14 ++ .../parsing/array_range_nested.sol | 12 + .../parsing/array_range_no_start.sol | 6 + .../syntaxTests/parsing/array_type_range.sol | 14 ++ .../abidecode/abi_decode_invalid_arg_type.sol | 2 +- 50 files changed, 655 insertions(+), 101 deletions(-) create mode 100644 test/libsolidity/semanticTests/abiDecodeV1/decode_slice.sol create mode 100644 test/libsolidity/semanticTests/array/calldata_slice_access.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/bytes_calldata.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/bytes_memory.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/bytes_storage.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/calldata_dynamic.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/calldata_dynamic_access.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/calldata_dynamic_convert_to_memory.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/calldata_dynamic_encode.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/calldata_dynamic_forward.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/calldata_static.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/memory_dynamic.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/memory_static.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/slice_literal.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/slice_memory_bytes.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/slice_memory_string.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/slice_string.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/storage_dynamic.sol create mode 100644 test/libsolidity/syntaxTests/array/slice/storage_static.sol create mode 100644 test/libsolidity/syntaxTests/parsing/array_range_and_ternary.sol create mode 100644 test/libsolidity/syntaxTests/parsing/array_range_conversion.sol create mode 100644 test/libsolidity/syntaxTests/parsing/array_range_nested.sol create mode 100644 test/libsolidity/syntaxTests/parsing/array_range_no_start.sol create mode 100644 test/libsolidity/syntaxTests/parsing/array_type_range.sol diff --git a/Changelog.md b/Changelog.md index cadd3884a912..1151b3d7c8e7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,6 +14,7 @@ Language Features: * Allow global enums and structs. * Allow underscores as delimiters in hex strings. * Allow explicit conversions from ``address`` to ``address payable`` via ``payable(...)``. + * Introduce syntax for array slices and implement them for dynamic calldata arrays. Compiler Features: diff --git a/docs/grammar.txt b/docs/grammar.txt index cf0ddd1046c7..4433b4a4308a 100644 --- a/docs/grammar.txt +++ b/docs/grammar.txt @@ -86,6 +86,7 @@ Expression = Expression ('++' | '--') | NewExpression | IndexAccess + | IndexRangeAccess | MemberAccess | FunctionCall | '(' Expression ')' @@ -123,6 +124,7 @@ FunctionCallArguments = '{' NameValueList? '}' NewExpression = 'new' TypeName MemberAccess = Expression '.' Identifier IndexAccess = Expression '[' Expression? ']' +IndexRangeAccess = Expression '[' Expression? ':' Expression? ']' BooleanLiteral = 'true' | 'false' NumberLiteral = ( HexNumber | DecimalNumber ) (' ' NumberUnit)? diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index d1faa6882c8f..2ac071375bda 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -136,19 +136,17 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c ); if (arguments.size() >= 1) - { - BoolResult result = type(*arguments.front())->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()); - - if (!result) - m_errorReporter.typeErrorConcatenateDescriptions( + if ( + !type(*arguments.front())->isImplicitlyConvertibleTo(*TypeProvider::bytesMemory()) && + !type(*arguments.front())->isImplicitlyConvertibleTo(*TypeProvider::bytesCalldata()) + ) + m_errorReporter.typeError( arguments.front()->location(), - "Invalid type for argument in function call. " - "Invalid implicit conversion from " + + "The first argument to \"abi.decode\" must be implicitly convertible to " + "bytes memory or bytes calldata, but is of type " + type(*arguments.front())->toString() + - " to bytes memory requested.", - result.message() + "." ); - } if (arguments.size() < 2) return {}; @@ -2245,6 +2243,14 @@ bool TypeChecker::visit(IndexAccess const& _access) Expression const* index = _access.indexExpression(); switch (baseType->category()) { + case Type::Category::ArraySlice: + { + auto const& arrayType = dynamic_cast(*baseType).arrayType(); + if (arrayType.location() != DataLocation::CallData || !arrayType.isDynamicallySized()) + m_errorReporter.typeError(_access.location(), "Index access is only implemented for slices of dynamic calldata arrays."); + baseType = &arrayType; + [[fallthrough]]; + } case Type::Category::Array: { ArrayType const& actualType = dynamic_cast(*baseType); @@ -2341,6 +2347,50 @@ bool TypeChecker::visit(IndexAccess const& _access) return false; } +bool TypeChecker::visit(IndexRangeAccess const& _access) +{ + _access.baseExpression().accept(*this); + + bool isLValue = false; // TODO: set this correctly when implementing slices for memory and storage arrays + bool isPure = _access.baseExpression().annotation().isPure; + + if (Expression const* start = _access.startExpression()) + { + expectType(*start, *TypeProvider::uint256()); + if (!start->annotation().isPure) + isPure = false; + } + if (Expression const* end = _access.endExpression()) + { + expectType(*end, *TypeProvider::uint256()); + if (!end->annotation().isPure) + isPure = false; + } + + TypePointer exprType = type(_access.baseExpression()); + if (exprType->category() == Type::Category::TypeType) + { + m_errorReporter.typeError(_access.location(), "Types cannot be sliced."); + _access.annotation().type = exprType; + return false; + } + + ArrayType const* arrayType = nullptr; + if (auto const* arraySlice = dynamic_cast(exprType)) + arrayType = &arraySlice->arrayType(); + else if (!(arrayType = dynamic_cast(exprType))) + m_errorReporter.fatalTypeError(_access.location(), "Index range access is only possible for arrays and array slices."); + + + if (arrayType->location() != DataLocation::CallData || !arrayType->isDynamicallySized()) + m_errorReporter.typeError(_access.location(), "Index range access is only supported for dynamic calldata arrays."); + _access.annotation().type = TypeProvider::arraySlice(*arrayType); + _access.annotation().isLValue = isLValue; + _access.annotation().isPure = isPure; + + return false; +} + bool TypeChecker::visit(Identifier const& _identifier) { IdentifierAnnotation& annotation = _identifier.annotation(); diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index 8f532a89cfd4..c962ad2ed80b 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -136,6 +136,7 @@ class TypeChecker: private ASTConstVisitor void endVisit(NewExpression const& _newExpression) override; bool visit(MemberAccess const& _memberAccess) override; bool visit(IndexAccess const& _indexAccess) override; + bool visit(IndexRangeAccess const& _indexRangeAccess) override; bool visit(Identifier const& _identifier) override; void endVisit(ElementaryTypeNameExpression const& _expr) override; void endVisit(Literal const& _literal) override; diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index cf35a4889a95..7ead355e1f26 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -413,6 +413,13 @@ void ViewPureChecker::endVisit(IndexAccess const& _indexAccess) } } +void ViewPureChecker::endVisit(IndexRangeAccess const& _indexRangeAccess) +{ + bool writes = _indexRangeAccess.annotation().lValueRequested; + if (_indexRangeAccess.baseExpression().annotation().type->dataStoredIn(DataLocation::Storage)) + reportMutability(writes ? StateMutability::NonPayable : StateMutability::View, _indexRangeAccess.location()); +} + void ViewPureChecker::endVisit(ModifierInvocation const& _modifier) { solAssert(_modifier.name(), ""); diff --git a/libsolidity/analysis/ViewPureChecker.h b/libsolidity/analysis/ViewPureChecker.h index fd2432a7dae7..b697253f146c 100644 --- a/libsolidity/analysis/ViewPureChecker.h +++ b/libsolidity/analysis/ViewPureChecker.h @@ -58,6 +58,7 @@ class ViewPureChecker: private ASTConstVisitor bool visit(MemberAccess const& _memberAccess) override; void endVisit(MemberAccess const& _memberAccess) override; void endVisit(IndexAccess const& _indexAccess) override; + void endVisit(IndexRangeAccess const& _indexAccess) override; void endVisit(ModifierInvocation const& _modifier) override; void endVisit(FunctionCall const& _functionCall) override; void endVisit(InlineAssembly const& _inlineAssembly) override; diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index e808003ec90e..7412626823ad 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -1642,6 +1642,32 @@ class IndexAccess: public Expression ASTPointer m_index; }; +/** + * Index range access to an array. Example: a[2:3] + */ +class IndexRangeAccess: public Expression +{ +public: + IndexRangeAccess( + SourceLocation const& _location, + ASTPointer const& _base, + ASTPointer const& _start, + ASTPointer const& _end + ): + Expression(_location), m_base(_base), m_start(_start), m_end(_end) {} + void accept(ASTVisitor& _visitor) override; + void accept(ASTConstVisitor& _visitor) const override; + + Expression const& baseExpression() const { return *m_base; } + Expression const* startExpression() const { return m_start.get(); } + Expression const* endExpression() const { return m_end.get(); } + +private: + ASTPointer m_base; + ASTPointer m_start; + ASTPointer m_end; +}; + /** * Primary expression, i.e. an expression that cannot be divided any further. Examples are literals * or variable references. diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index c6f7ecf9b4c7..ed5b56d71043 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -694,6 +694,18 @@ bool ASTJsonConverter::visit(IndexAccess const& _node) return false; } +bool ASTJsonConverter::visit(IndexRangeAccess const& _node) +{ + std::vector> attributes = { + make_pair("baseExpression", toJson(_node.baseExpression())), + make_pair("startExpression", toJsonOrNull(_node.startExpression())), + make_pair("endExpression", toJsonOrNull(_node.endExpression())), + }; + appendExpressionAttributes(attributes, _node.annotation()); + setJsonNode(_node, "IndexRangeAccess", std::move(attributes)); + return false; +} + bool ASTJsonConverter::visit(Identifier const& _node) { Json::Value overloads(Json::arrayValue); diff --git a/libsolidity/ast/ASTJsonConverter.h b/libsolidity/ast/ASTJsonConverter.h index 7cd1dde39b87..0c79d63d13a8 100644 --- a/libsolidity/ast/ASTJsonConverter.h +++ b/libsolidity/ast/ASTJsonConverter.h @@ -111,6 +111,7 @@ class ASTJsonConverter: public ASTConstVisitor bool visit(NewExpression const& _node) override; bool visit(MemberAccess const& _node) override; bool visit(IndexAccess const& _node) override; + bool visit(IndexRangeAccess const& _node) override; bool visit(Identifier const& _node) override; bool visit(ElementaryTypeNameExpression const& _node) override; bool visit(Literal const& _node) override; diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h index 6184e5f4270e..901b93ef8b27 100644 --- a/libsolidity/ast/ASTVisitor.h +++ b/libsolidity/ast/ASTVisitor.h @@ -87,6 +87,7 @@ class ASTVisitor virtual bool visit(NewExpression& _node) { return visitNode(_node); } virtual bool visit(MemberAccess& _node) { return visitNode(_node); } virtual bool visit(IndexAccess& _node) { return visitNode(_node); } + virtual bool visit(IndexRangeAccess& _node) { return visitNode(_node); } virtual bool visit(Identifier& _node) { return visitNode(_node); } virtual bool visit(ElementaryTypeNameExpression& _node) { return visitNode(_node); } virtual bool visit(Literal& _node) { return visitNode(_node); } @@ -134,6 +135,7 @@ class ASTVisitor virtual void endVisit(NewExpression& _node) { endVisitNode(_node); } virtual void endVisit(MemberAccess& _node) { endVisitNode(_node); } virtual void endVisit(IndexAccess& _node) { endVisitNode(_node); } + virtual void endVisit(IndexRangeAccess& _node) { endVisitNode(_node); } virtual void endVisit(Identifier& _node) { endVisitNode(_node); } virtual void endVisit(ElementaryTypeNameExpression& _node) { endVisitNode(_node); } virtual void endVisit(Literal& _node) { endVisitNode(_node); } @@ -194,6 +196,7 @@ class ASTConstVisitor virtual bool visit(NewExpression const& _node) { return visitNode(_node); } virtual bool visit(MemberAccess const& _node) { return visitNode(_node); } virtual bool visit(IndexAccess const& _node) { return visitNode(_node); } + virtual bool visit(IndexRangeAccess const& _node) { return visitNode(_node); } virtual bool visit(Identifier const& _node) { return visitNode(_node); } virtual bool visit(ElementaryTypeNameExpression const& _node) { return visitNode(_node); } virtual bool visit(Literal const& _node) { return visitNode(_node); } @@ -241,6 +244,7 @@ class ASTConstVisitor virtual void endVisit(NewExpression const& _node) { endVisitNode(_node); } virtual void endVisit(MemberAccess const& _node) { endVisitNode(_node); } virtual void endVisit(IndexAccess const& _node) { endVisitNode(_node); } + virtual void endVisit(IndexRangeAccess const& _node) { endVisitNode(_node); } virtual void endVisit(Identifier const& _node) { endVisitNode(_node); } virtual void endVisit(ElementaryTypeNameExpression const& _node) { endVisitNode(_node); } virtual void endVisit(Literal const& _node) { endVisitNode(_node); } diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h index a95c22d7b544..fd676c1ea008 100644 --- a/libsolidity/ast/AST_accept.h +++ b/libsolidity/ast/AST_accept.h @@ -783,6 +783,32 @@ void IndexAccess::accept(ASTConstVisitor& _visitor) const _visitor.endVisit(*this); } +void IndexRangeAccess::accept(ASTVisitor& _visitor) +{ + if (_visitor.visit(*this)) + { + m_base->accept(_visitor); + if (m_start) + m_start->accept(_visitor); + if (m_end) + m_end->accept(_visitor); + } + _visitor.endVisit(*this); +} + +void IndexRangeAccess::accept(ASTConstVisitor& _visitor) const +{ + if (_visitor.visit(*this)) + { + m_base->accept(_visitor); + if (m_start) + m_start->accept(_visitor); + if (m_end) + m_end->accept(_visitor); + } + _visitor.endVisit(*this); +} + void Identifier::accept(ASTVisitor& _visitor) { _visitor.visit(*this); diff --git a/libsolidity/ast/TypeProvider.cpp b/libsolidity/ast/TypeProvider.cpp index 7d7824da3fb3..a9b4fafb60dd 100644 --- a/libsolidity/ast/TypeProvider.cpp +++ b/libsolidity/ast/TypeProvider.cpp @@ -31,6 +31,7 @@ InaccessibleDynamicType const TypeProvider::m_inaccessibleDynamic{}; /// they rely on `byte` being available which we cannot guarantee in the static init context. unique_ptr TypeProvider::m_bytesStorage; unique_ptr TypeProvider::m_bytesMemory; +unique_ptr TypeProvider::m_bytesCalldata; unique_ptr TypeProvider::m_stringStorage; unique_ptr TypeProvider::m_stringMemory; @@ -177,6 +178,7 @@ void TypeProvider::reset() clearCache(m_inaccessibleDynamic); clearCache(m_bytesStorage); clearCache(m_bytesMemory); + clearCache(m_bytesCalldata); clearCache(m_stringStorage); clearCache(m_stringMemory); clearCache(m_emptyTuple); @@ -314,6 +316,13 @@ ArrayType const* TypeProvider::bytesMemory() return m_bytesMemory.get(); } +ArrayType const* TypeProvider::bytesCalldata() +{ + if (!m_bytesCalldata) + m_bytesCalldata = make_unique(DataLocation::CallData, false); + return m_bytesCalldata.get(); +} + ArrayType const* TypeProvider::stringStorage() { if (!m_stringStorage) @@ -500,6 +509,11 @@ ArrayType const* TypeProvider::array(DataLocation _location, Type const* _baseTy return createAndGet(_location, _baseType, _length); } +ArraySliceType const* TypeProvider::arraySlice(ArrayType const& _arrayType) +{ + return createAndGet(_arrayType); +} + ContractType const* TypeProvider::contract(ContractDefinition const& _contractDef, bool _isSuper) { return createAndGet(_contractDef, _isSuper); diff --git a/libsolidity/ast/TypeProvider.h b/libsolidity/ast/TypeProvider.h index f6f4e1f7430d..f65563e2aad1 100644 --- a/libsolidity/ast/TypeProvider.h +++ b/libsolidity/ast/TypeProvider.h @@ -68,6 +68,7 @@ class TypeProvider static ArrayType const* bytesStorage(); static ArrayType const* bytesMemory(); + static ArrayType const* bytesCalldata(); static ArrayType const* stringStorage(); static ArrayType const* stringMemory(); @@ -80,6 +81,8 @@ class TypeProvider /// Constructor for a fixed-size array type ("type[20]") static ArrayType const* array(DataLocation _location, Type const* _baseType, u256 const& _length); + static ArraySliceType const* arraySlice(ArrayType const& _arrayType); + static AddressType const* payableAddress() noexcept { return &m_payableAddress; } static AddressType const* address() noexcept { return &m_address; } @@ -203,6 +206,7 @@ class TypeProvider /// These are lazy-initialized because they depend on `byte` being available. static std::unique_ptr m_bytesStorage; static std::unique_ptr m_bytesMemory; + static std::unique_ptr m_bytesCalldata; static std::unique_ptr m_stringStorage; static std::unique_ptr m_stringMemory; diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 79d41bfe9265..b509c24957a8 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1869,6 +1869,30 @@ std::unique_ptr ArrayType::copyForLocation(DataLocation _location return copy; } +BoolResult ArraySliceType::isImplicitlyConvertibleTo(Type const& _other) const +{ + if (m_arrayType.location() == DataLocation::CallData && m_arrayType.isDynamicallySized() && m_arrayType == _other) + return true; + return (*this) == _other; +} + +string ArraySliceType::richIdentifier() const +{ + return m_arrayType.richIdentifier() + "_slice"; +} + +bool ArraySliceType::operator==(Type const& _other) const +{ + if (auto const* other = dynamic_cast(&_other)) + return m_arrayType == other->m_arrayType; + return false; +} + +string ArraySliceType::toString(bool _short) const +{ + return m_arrayType.toString(_short) + " slice"; +} + string ContractType::richIdentifier() const { return (m_super ? "t_super" : "t_contract") + parenthesizeUserIdentifier(m_contract.name()) + to_string(m_contract.id()); diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 992d95552fa9..8563c839f35f 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -161,7 +161,7 @@ class Type enum class Category { - Address, Integer, RationalNumber, StringLiteral, Bool, FixedPoint, Array, + Address, Integer, RationalNumber, StringLiteral, Bool, FixedPoint, Array, ArraySlice, FixedBytes, Contract, Struct, Function, Enum, Tuple, Mapping, TypeType, Modifier, Magic, Module, InaccessibleDynamic @@ -773,6 +773,35 @@ class ArrayType: public ReferenceType mutable boost::optional m_interfaceType_library; }; +class ArraySliceType: public ReferenceType +{ +public: + explicit ArraySliceType(ArrayType const& _arrayType): ReferenceType(_arrayType.location()), m_arrayType(_arrayType) {} + Category category() const override { return Category::ArraySlice; } + + BoolResult isImplicitlyConvertibleTo(Type const& _other) const override; + std::string richIdentifier() const override; + bool operator==(Type const& _other) const override; + unsigned calldataEncodedSize(bool) const override { solAssert(false, ""); } + unsigned calldataEncodedTailSize() const override { return 32; } + bool isDynamicallySized() const override { return true; } + bool isDynamicallyEncoded() const override { return true; } + bool canLiveOutsideStorage() const override { return m_arrayType.canLiveOutsideStorage(); } + unsigned sizeOnStack() const override { return 2; } + std::string toString(bool _short) const override; + + /// @returns true if this is valid to be stored in calldata + bool validForCalldata() const { return m_arrayType.validForCalldata(); } + + ArrayType const& arrayType() const { return m_arrayType; } + u256 memoryDataSize() const override { solAssert(false, ""); } + + std::unique_ptr copyForLocation(DataLocation, bool) const override { solAssert(false, ""); } + +private: + ArrayType const& m_arrayType; +}; + /** * The type of a contract instance or library, there is one distinct type for each contract definition. */ diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 0e10b3691a08..dfeb28db2587 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -981,6 +981,17 @@ void CompilerUtils::convertType( } break; } + case Type::Category::ArraySlice: + { + auto& typeOnStack = dynamic_cast(_typeOnStack); + solAssert(_targetType == typeOnStack.arrayType(), ""); + solUnimplementedAssert( + typeOnStack.arrayType().location() == DataLocation::CallData && + typeOnStack.arrayType().isDynamicallySized(), + "" + ); + break; + } case Type::Category::Struct: { solAssert(targetTypeCategory == stackTypeCategory, ""); diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 71c998c095b6..87f1a9d39e08 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1079,10 +1079,14 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) else targetTypes = TypePointers{_functionCall.annotation().type}; if ( - *firstArgType == ArrayType(DataLocation::CallData) || - *firstArgType == ArrayType(DataLocation::CallData, true) + auto referenceType = dynamic_cast(firstArgType); + referenceType && referenceType->dataStoredIn(DataLocation::CallData) ) + { + solAssert(referenceType->isImplicitlyConvertibleTo(*TypeProvider::bytesCalldata()), ""); + utils().convertType(*referenceType, *TypeProvider::bytesCalldata()); utils().abiDecode(targetTypes, false); + } else { utils().convertType(*firstArgType, *TypeProvider::bytesMemory()); @@ -1503,90 +1507,149 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) Type const& baseType = *_indexAccess.baseExpression().annotation().type; - if (baseType.category() == Type::Category::Mapping) + switch (baseType.category()) { - // stack: storage_base_ref - TypePointer keyType = dynamic_cast(baseType).keyType(); - solAssert(_indexAccess.indexExpression(), "Index expression expected."); - if (keyType->isDynamicallySized()) - { - _indexAccess.indexExpression()->accept(*this); - utils().fetchFreeMemoryPointer(); - // stack: base index mem - // note: the following operations must not allocate memory! - utils().packedEncode( - TypePointers{_indexAccess.indexExpression()->annotation().type}, - TypePointers{keyType} - ); - m_context << Instruction::SWAP1; - utils().storeInMemoryDynamic(*TypeProvider::uint256()); - utils().toSizeAfterFreeMemoryPointer(); - } - else + case Type::Category::Mapping: { - m_context << u256(0); // memory position - appendExpressionCopyToMemory(*keyType, *_indexAccess.indexExpression()); - m_context << Instruction::SWAP1; - solAssert(CompilerUtils::freeMemoryPointer >= 0x40, ""); - utils().storeInMemoryDynamic(*TypeProvider::uint256()); + // stack: storage_base_ref + TypePointer keyType = dynamic_cast(baseType).keyType(); + solAssert(_indexAccess.indexExpression(), "Index expression expected."); + if (keyType->isDynamicallySized()) + { + _indexAccess.indexExpression()->accept(*this); + utils().fetchFreeMemoryPointer(); + // stack: base index mem + // note: the following operations must not allocate memory! + utils().packedEncode( + TypePointers{_indexAccess.indexExpression()->annotation().type}, + TypePointers{keyType} + ); + m_context << Instruction::SWAP1; + utils().storeInMemoryDynamic(*TypeProvider::uint256()); + utils().toSizeAfterFreeMemoryPointer(); + } + else + { + m_context << u256(0); // memory position + appendExpressionCopyToMemory(*keyType, *_indexAccess.indexExpression()); + m_context << Instruction::SWAP1; + solAssert(CompilerUtils::freeMemoryPointer >= 0x40, ""); + utils().storeInMemoryDynamic(*TypeProvider::uint256()); + m_context << u256(0); + } + m_context << Instruction::KECCAK256; m_context << u256(0); + setLValueToStorageItem(_indexAccess); + break; } - m_context << Instruction::KECCAK256; - m_context << u256(0); - setLValueToStorageItem(_indexAccess); - } - else if (baseType.category() == Type::Category::Array) - { - ArrayType const& arrayType = dynamic_cast(baseType); - solAssert(_indexAccess.indexExpression(), "Index expression expected."); + case Type::Category::ArraySlice: + { + auto const& arrayType = dynamic_cast(baseType).arrayType(); + solAssert(arrayType.location() == DataLocation::CallData && arrayType.isDynamicallySized(), ""); + solAssert(_indexAccess.indexExpression(), "Index expression expected."); + + acceptAndConvert(*_indexAccess.indexExpression(), *TypeProvider::uint256(), true); + ArrayUtils(m_context).accessCallDataArrayElement(arrayType); + break; - acceptAndConvert(*_indexAccess.indexExpression(), *TypeProvider::uint256(), true); - // stack layout: [] - switch (arrayType.location()) + } + case Type::Category::Array: { - case DataLocation::Storage: - ArrayUtils(m_context).accessIndex(arrayType); - if (arrayType.isByteArray()) + ArrayType const& arrayType = dynamic_cast(baseType); + solAssert(_indexAccess.indexExpression(), "Index expression expected."); + + acceptAndConvert(*_indexAccess.indexExpression(), *TypeProvider::uint256(), true); + // stack layout: [] + switch (arrayType.location()) { - solAssert(!arrayType.isString(), "Index access to string is not allowed."); - setLValue(_indexAccess); + case DataLocation::Storage: + ArrayUtils(m_context).accessIndex(arrayType); + if (arrayType.isByteArray()) + { + solAssert(!arrayType.isString(), "Index access to string is not allowed."); + setLValue(_indexAccess); + } + else + setLValueToStorageItem(_indexAccess); + break; + case DataLocation::Memory: + ArrayUtils(m_context).accessIndex(arrayType); + setLValue(_indexAccess, *_indexAccess.annotation().type, !arrayType.isByteArray()); + break; + case DataLocation::CallData: + ArrayUtils(m_context).accessCallDataArrayElement(arrayType); + break; } - else - setLValueToStorageItem(_indexAccess); break; - case DataLocation::Memory: - ArrayUtils(m_context).accessIndex(arrayType); - setLValue(_indexAccess, *_indexAccess.annotation().type, !arrayType.isByteArray()); + } + case Type::Category::FixedBytes: + { + FixedBytesType const& fixedBytesType = dynamic_cast(baseType); + solAssert(_indexAccess.indexExpression(), "Index expression expected."); + + acceptAndConvert(*_indexAccess.indexExpression(), *TypeProvider::uint256(), true); + // stack layout: + // check out-of-bounds access + m_context << u256(fixedBytesType.numBytes()); + m_context << Instruction::DUP2 << Instruction::LT << Instruction::ISZERO; + // out-of-bounds access throws exception + m_context.appendConditionalInvalid(); + + m_context << Instruction::BYTE; + utils().leftShiftNumberOnStack(256 - 8); break; - case DataLocation::CallData: - ArrayUtils(m_context).accessCallDataArrayElement(arrayType); + } + case Type::Category::TypeType: + { + solAssert(baseType.sizeOnStack() == 0, ""); + solAssert(_indexAccess.annotation().type->sizeOnStack() == 0, ""); + // no-op - this seems to be a lone array type (`structType[];`) break; } + default: + solAssert(false, "Index access only allowed for mappings or arrays."); + break; } - else if (baseType.category() == Type::Category::FixedBytes) - { - FixedBytesType const& fixedBytesType = dynamic_cast(baseType); - solAssert(_indexAccess.indexExpression(), "Index expression expected."); - - acceptAndConvert(*_indexAccess.indexExpression(), *TypeProvider::uint256(), true); - // stack layout: - // check out-of-bounds access - m_context << u256(fixedBytesType.numBytes()); - m_context << Instruction::DUP2 << Instruction::LT << Instruction::ISZERO; - // out-of-bounds access throws exception - m_context.appendConditionalInvalid(); - m_context << Instruction::BYTE; - utils().leftShiftNumberOnStack(256 - 8); - } - else if (baseType.category() == Type::Category::TypeType) - { - solAssert(baseType.sizeOnStack() == 0, ""); - solAssert(_indexAccess.annotation().type->sizeOnStack() == 0, ""); - // no-op - this seems to be a lone array type (`structType[];`) - } + return false; +} + +bool ExpressionCompiler::visit(IndexRangeAccess const& _indexAccess) +{ + CompilerContext::LocationSetter locationSetter(m_context, _indexAccess); + _indexAccess.baseExpression().accept(*this); + + Type const& baseType = *_indexAccess.baseExpression().annotation().type; + + ArrayType const *arrayType = dynamic_cast(&baseType); + if (!arrayType) + if (ArraySliceType const* sliceType = dynamic_cast(&baseType)) + arrayType = &sliceType->arrayType(); + + solAssert(arrayType, ""); + solUnimplementedAssert(arrayType->location() == DataLocation::CallData && arrayType->isDynamicallySized(), ""); + + if (_indexAccess.startExpression()) + acceptAndConvert(*_indexAccess.startExpression(), *TypeProvider::uint256()); + else + m_context << u256(0); + if (_indexAccess.endExpression()) + acceptAndConvert(*_indexAccess.endExpression(), *TypeProvider::uint256()); else - solAssert(false, "Index access only allowed for mappings or arrays."); + m_context << Instruction::DUP2; + + m_context.appendInlineAssembly( + Whiskers(R"({ + if gt(sliceStart, sliceEnd) { revert(0, 0) } + if gt(sliceEnd, length) { revert(0, 0) } + + offset := add(offset, mul(sliceStart, )) + length := sub(sliceEnd, sliceStart) + })")("stride", toString(arrayType->calldataStride())).render(), + {"offset", "length", "sliceStart", "sliceEnd"} + ); + + m_context << Instruction::POP << Instruction::POP; return false; } diff --git a/libsolidity/codegen/ExpressionCompiler.h b/libsolidity/codegen/ExpressionCompiler.h index 645d670670fa..8bdb1479afe9 100644 --- a/libsolidity/codegen/ExpressionCompiler.h +++ b/libsolidity/codegen/ExpressionCompiler.h @@ -80,6 +80,7 @@ class ExpressionCompiler: private ASTConstVisitor bool visit(NewExpression const& _newExpression) override; bool visit(MemberAccess const& _memberAccess) override; bool visit(IndexAccess const& _indexAccess) override; + bool visit(IndexRangeAccess const& _indexAccess) override; void endVisit(Identifier const& _identifier) override; void endVisit(Literal const& _literal) override; diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 9bb4a9984336..75d79db2f9e7 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -823,11 +823,6 @@ string YulUtilFunctions::memoryArrayIndexAccessFunction(ArrayType const& _type) }); } -string YulUtilFunctions::calldataArrayIndexAccessFunction(ArrayType const& /*_type*/) -{ - solUnimplemented("Calldata arrays not yet implemented!"); -} - string YulUtilFunctions::nextArrayElementFunction(ArrayType const& _type) { solAssert(!_type.isByteArray(), ""); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 2258707faef8..f978a8f60b55 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -941,6 +941,11 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess) solAssert(false, "Index access only allowed for mappings or arrays."); } +void IRGeneratorForStatements::endVisit(IndexRangeAccess const&) +{ + solUnimplementedAssert(false, "Index range accesses not yet implemented."); +} + void IRGeneratorForStatements::endVisit(Identifier const& _identifier) { Declaration const* declaration = _identifier.annotation().referencedDeclaration; diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.h b/libsolidity/codegen/ir/IRGeneratorForStatements.h index d64ab9e0a51d..74cef0b8aae6 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.h +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.h @@ -63,6 +63,7 @@ class IRGeneratorForStatements: public ASTConstVisitor void endVisit(MemberAccess const& _memberAccess) override; bool visit(InlineAssembly const& _inlineAsm) override; void endVisit(IndexAccess const& _indexAccess) override; + void endVisit(IndexRangeAccess const& _indexRangeAccess) override; void endVisit(Identifier const& _identifier) override; bool visit(Literal const& _literal) override; diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 421bfb3b6fb1..5df464548245 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -767,6 +767,15 @@ void SMTEncoder::endVisit(IndexAccess const& _indexAccess) m_uninterpretedTerms.insert(&_indexAccess); } +void SMTEncoder::endVisit(IndexRangeAccess const& _indexRangeAccess) +{ + createExpr(_indexRangeAccess); + m_errorReporter.warning( + _indexRangeAccess.location(), + "Assertion checker does not yet implement this expression." + ); +} + void SMTEncoder::arrayAssignment() { m_arrayAssignmentHappened = true; diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index 6ccbe9bccd5d..35a45e83d12b 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -86,6 +86,7 @@ class SMTEncoder: public ASTConstVisitor void endVisit(Return const& _node) override; bool visit(MemberAccess const& _node) override; void endVisit(IndexAccess const& _node) override; + void endVisit(IndexRangeAccess const& _node) override; bool visit(InlineAssembly const& _node) override; /// Do not visit subtree if node is a RationalNumber. diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 14c4a29fc2a2..9601389c7750 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1607,11 +1607,24 @@ ASTPointer Parser::parseLeftHandSideExpression( { m_scanner->next(); ASTPointer index; - if (m_scanner->currentToken() != Token::RBrack) + ASTPointer endIndex; + if (m_scanner->currentToken() != Token::RBrack && m_scanner->currentToken() != Token::Colon) index = parseExpression(); - nodeFactory.markEndPosition(); - expectToken(Token::RBrack); - expression = nodeFactory.createNode(expression, index); + if (m_scanner->currentToken() == Token::Colon) + { + expectToken(Token::Colon); + if (m_scanner->currentToken() != Token::RBrack) + endIndex = parseExpression(); + nodeFactory.markEndPosition(); + expectToken(Token::RBrack); + expression = nodeFactory.createNode(expression, index, endIndex); + } + else + { + nodeFactory.markEndPosition(); + expectToken(Token::RBrack); + expression = nodeFactory.createNode(expression, index); + } break; } case Token::Period: @@ -1861,12 +1874,25 @@ Parser::IndexAccessedPath Parser::parseIndexAccessedPath() { expectToken(Token::LBrack); ASTPointer index; - if (m_scanner->currentToken() != Token::RBrack) + if (m_scanner->currentToken() != Token::RBrack && m_scanner->currentToken() != Token::Colon) index = parseExpression(); SourceLocation indexLocation = iap.path.front()->location(); - indexLocation.end = endPosition(); - iap.indices.emplace_back(index, indexLocation); - expectToken(Token::RBrack); + if (m_scanner->currentToken() == Token::Colon) + { + expectToken(Token::Colon); + ASTPointer endIndex; + if (m_scanner->currentToken() != Token::RBrack) + endIndex = parseExpression(); + indexLocation.end = endPosition(); + iap.indices.emplace_back(IndexAccessedPath::Index{index, {endIndex}, indexLocation}); + expectToken(Token::RBrack); + } + else + { + indexLocation.end = endPosition(); + iap.indices.emplace_back(IndexAccessedPath::Index{index, {}, indexLocation}); + expectToken(Token::RBrack); + } } return iap; @@ -1898,8 +1924,10 @@ ASTPointer Parser::typeNameFromIndexAccessStructure(Parser::IndexAcces } for (auto const& lengthExpression: _iap.indices) { - nodeFactory.setLocation(lengthExpression.second); - type = nodeFactory.createNode(type, lengthExpression.first); + if (lengthExpression.end) + parserError(lengthExpression.location, "Expected array length expression."); + nodeFactory.setLocation(lengthExpression.location); + type = nodeFactory.createNode(type, lengthExpression.start); } return type; } @@ -1927,8 +1955,11 @@ ASTPointer Parser::expressionFromIndexAccessStructure( } for (auto const& index: _iap.indices) { - nodeFactory.setLocation(index.second); - expression = nodeFactory.createNode(expression, index.first); + nodeFactory.setLocation(index.location); + if (index.end) + expression = nodeFactory.createNode(expression, index.start, *index.end); + else + expression = nodeFactory.createNode(expression, index.start); } return expression; } diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index b0e1c6716516..479306fb00eb 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -162,8 +162,14 @@ class Parser: public langutil::ParserBase /// or to a type name. For this to be valid, path cannot be empty, but indices can be empty. struct IndexAccessedPath { + struct Index + { + ASTPointer start; + std::optional> end; + langutil::SourceLocation location; + }; std::vector> path; - std::vector, langutil::SourceLocation>> indices; + std::vector indices; bool empty() const; }; diff --git a/test/libsolidity/semanticTests/abiDecodeV1/decode_slice.sol b/test/libsolidity/semanticTests/abiDecodeV1/decode_slice.sol new file mode 100644 index 000000000000..35cb15077abc --- /dev/null +++ b/test/libsolidity/semanticTests/abiDecodeV1/decode_slice.sol @@ -0,0 +1,9 @@ +contract C { + function f(uint256 a, uint256 b) external returns (uint256 c, uint256 d, uint256 e, uint256 f) { + (c, d) = abi.decode(msg.data[4:], (uint256, uint256)); + e = abi.decode(msg.data[4 : 4 + 32], (uint256)); + f = abi.decode(msg.data[4 + 32 : 4 + 32 + 32], (uint256)); + } +} +// ---- +// f(uint256,uint256): 42, 23 -> 42, 23, 42, 23 diff --git a/test/libsolidity/semanticTests/array/calldata_slice_access.sol b/test/libsolidity/semanticTests/array/calldata_slice_access.sol new file mode 100644 index 000000000000..8e8a398de268 --- /dev/null +++ b/test/libsolidity/semanticTests/array/calldata_slice_access.sol @@ -0,0 +1,44 @@ +contract C { + function f(uint256[] calldata x, uint256 start, uint256 end) external pure { + x[start:end]; + } + function g(uint256[] calldata x, uint256 start, uint256 end, uint256 index) external pure returns (uint256, uint256, uint256) { + return (x[start:end][index], x[start:][0:end-start][index], x[:end][start:][index]); + } +} +// ---- +// f(uint256[],uint256,uint256): 0x80, 0, 0, 0, 1, 42 -> +// f(uint256[],uint256,uint256): 0x80, 0, 1, 0, 1, 42 -> +// f(uint256[],uint256,uint256): 0x80, 0, 2, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 1, 0, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 1, 1, 0, 1, 42 -> +// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 2, 0, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 2, 1, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 2, 2, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 0, 2, 1, 0, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, 1, 2, 0, 2, 42, 23 -> +// f(uint256[],uint256,uint256): 0x80, 1, 3, 0, 2, 42, 23 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, -1, 0, 0, 1, 42 -> FAILURE +// f(uint256[],uint256,uint256): 0x80, -1, -1, 0, 1, 42 -> FAILURE +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 1, 42 -> 42, 42, 42 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 1, 42 -> FAILURE +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 0, 0, 1, 42 -> FAILURE +// g(uint256[],uint256,uint256,uint256): 0x80, 1, 1, 0, 1, 42 -> FAILURE +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 5, 5, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE +// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202 +// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 3, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205 +// g(uint256[],uint256,uint256,uint256): 0x80, 1, 5, 4, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE +// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205 +// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE +// g(uint256[],uint256,uint256,uint256): 0x80, 5, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4201, 0x4201, 0x4201 +// g(uint256[],uint256,uint256,uint256): 0x80, 0, 1, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE +// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4202, 0x4202, 0x4202 +// g(uint256[],uint256,uint256,uint256): 0x80, 1, 2, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE +// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 0, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> 0x4205, 0x4205, 0x4205 +// g(uint256[],uint256,uint256,uint256): 0x80, 4, 5, 1, 5, 0x4201, 0x4202, 0x4203, 0x4204, 0x4205 -> FAILURE diff --git a/test/libsolidity/syntaxTests/array/slice/bytes_calldata.sol b/test/libsolidity/syntaxTests/array/slice/bytes_calldata.sol new file mode 100644 index 000000000000..64126f53c9f9 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/bytes_calldata.sol @@ -0,0 +1,5 @@ +contract C { + function f(bytes calldata x) external pure { + x[1:2]; + } +} diff --git a/test/libsolidity/syntaxTests/array/slice/bytes_memory.sol b/test/libsolidity/syntaxTests/array/slice/bytes_memory.sol new file mode 100644 index 000000000000..c2bfc4f6213d --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/bytes_memory.sol @@ -0,0 +1,7 @@ +contract C { + function f(bytes memory x) public pure { + x[1:2]; + } +} +// ---- +// TypeError: (66-72): Index range access is only supported for dynamic calldata arrays. diff --git a/test/libsolidity/syntaxTests/array/slice/bytes_storage.sol b/test/libsolidity/syntaxTests/array/slice/bytes_storage.sol new file mode 100644 index 000000000000..dd7ed0893594 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/bytes_storage.sol @@ -0,0 +1,8 @@ +contract C { + bytes x; + function f() public view { + x[1:2]; + } +} +// ---- +// TypeError: (65-71): Index range access is only supported for dynamic calldata arrays. diff --git a/test/libsolidity/syntaxTests/array/slice/calldata_dynamic.sol b/test/libsolidity/syntaxTests/array/slice/calldata_dynamic.sol new file mode 100644 index 000000000000..ea0672a43fda --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/calldata_dynamic.sol @@ -0,0 +1,5 @@ +contract C { + function f(uint256[] calldata x) external pure { + x[1:2]; + } +} diff --git a/test/libsolidity/syntaxTests/array/slice/calldata_dynamic_access.sol b/test/libsolidity/syntaxTests/array/slice/calldata_dynamic_access.sol new file mode 100644 index 000000000000..65088f4c2ae5 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/calldata_dynamic_access.sol @@ -0,0 +1,9 @@ +contract C { + function f(uint256[] calldata x) external pure { + x[1:2][0]; + x[1:][0]; + x[1:][1:2][0]; + x[1:2][1:][0]; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/array/slice/calldata_dynamic_convert_to_memory.sol b/test/libsolidity/syntaxTests/array/slice/calldata_dynamic_convert_to_memory.sol new file mode 100644 index 000000000000..a3e2fccc1cc8 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/calldata_dynamic_convert_to_memory.sol @@ -0,0 +1,7 @@ +contract C { + function f(bytes calldata x) external { + bytes memory y = x[1:2]; + } +} +// ---- +// TypeError: (65-88): Type bytes calldata slice is not implicitly convertible to expected type bytes memory. diff --git a/test/libsolidity/syntaxTests/array/slice/calldata_dynamic_encode.sol b/test/libsolidity/syntaxTests/array/slice/calldata_dynamic_encode.sol new file mode 100644 index 000000000000..a31e5ab85abe --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/calldata_dynamic_encode.sol @@ -0,0 +1,7 @@ +contract C { + function f(uint256[] calldata x) external pure { + abi.encode(x[1:2]); + } +} +// ---- +// TypeError: (85-91): This type cannot be encoded. diff --git a/test/libsolidity/syntaxTests/array/slice/calldata_dynamic_forward.sol b/test/libsolidity/syntaxTests/array/slice/calldata_dynamic_forward.sol new file mode 100644 index 000000000000..a2d6e0f02183 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/calldata_dynamic_forward.sol @@ -0,0 +1,7 @@ +contract C { + function f(bytes calldata x) external { + return this.f(x[1:2]); + } +} +// ---- +// TypeError: (79-85): Invalid type for argument in function call. Invalid implicit conversion from bytes calldata slice to bytes memory requested. diff --git a/test/libsolidity/syntaxTests/array/slice/calldata_static.sol b/test/libsolidity/syntaxTests/array/slice/calldata_static.sol new file mode 100644 index 000000000000..0fca7ff3c218 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/calldata_static.sol @@ -0,0 +1,7 @@ +contract C { + function f(uint256[42] calldata x) external pure { + x[1:2]; + } +} +// ---- +// TypeError: (76-82): Index range access is only supported for dynamic calldata arrays. diff --git a/test/libsolidity/syntaxTests/array/slice/memory_dynamic.sol b/test/libsolidity/syntaxTests/array/slice/memory_dynamic.sol new file mode 100644 index 000000000000..d6dbbc2706fd --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/memory_dynamic.sol @@ -0,0 +1,7 @@ +contract C { + function f(uint256[] memory x) public pure { + x[1:2]; + } +} +// ---- +// TypeError: (70-76): Index range access is only supported for dynamic calldata arrays. diff --git a/test/libsolidity/syntaxTests/array/slice/memory_static.sol b/test/libsolidity/syntaxTests/array/slice/memory_static.sol new file mode 100644 index 000000000000..dc12cb660ca1 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/memory_static.sol @@ -0,0 +1,7 @@ +contract C { + function f(uint256[42] memory x) public pure { + x[1:2]; + } +} +// ---- +// TypeError: (72-78): Index range access is only supported for dynamic calldata arrays. diff --git a/test/libsolidity/syntaxTests/array/slice/slice_literal.sol b/test/libsolidity/syntaxTests/array/slice/slice_literal.sol new file mode 100644 index 000000000000..9164c10db4d7 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/slice_literal.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure { + 1[1:]; + } +} +// ---- +// TypeError: (52-57): Index range access is only possible for arrays and array slices. diff --git a/test/libsolidity/syntaxTests/array/slice/slice_memory_bytes.sol b/test/libsolidity/syntaxTests/array/slice/slice_memory_bytes.sol new file mode 100644 index 000000000000..88e7f0596a7f --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/slice_memory_bytes.sol @@ -0,0 +1,8 @@ +contract C { + function f() public pure { + bytes memory y; + y[1:2]; + } +} +// ---- +// TypeError: (76-82): Index range access is only supported for dynamic calldata arrays. diff --git a/test/libsolidity/syntaxTests/array/slice/slice_memory_string.sol b/test/libsolidity/syntaxTests/array/slice/slice_memory_string.sol new file mode 100644 index 000000000000..cb0b1f4c396b --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/slice_memory_string.sol @@ -0,0 +1,8 @@ +contract C { + function f() public pure { + string memory y; + y[1:2]; + } +} +// ---- +// TypeError: (77-83): Index range access is only supported for dynamic calldata arrays. diff --git a/test/libsolidity/syntaxTests/array/slice/slice_string.sol b/test/libsolidity/syntaxTests/array/slice/slice_string.sol new file mode 100644 index 000000000000..593fbe9fa4c3 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/slice_string.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure { + ""[1:]; + } +} +// ---- +// TypeError: (52-58): Index range access is only possible for arrays and array slices. diff --git a/test/libsolidity/syntaxTests/array/slice/storage_dynamic.sol b/test/libsolidity/syntaxTests/array/slice/storage_dynamic.sol new file mode 100644 index 000000000000..c02afd55a8aa --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/storage_dynamic.sol @@ -0,0 +1,8 @@ +contract C { + uint256[] x; + function f() public view { + x[1:2]; + } +} +// ---- +// TypeError: (69-75): Index range access is only supported for dynamic calldata arrays. diff --git a/test/libsolidity/syntaxTests/array/slice/storage_static.sol b/test/libsolidity/syntaxTests/array/slice/storage_static.sol new file mode 100644 index 000000000000..77d619d777d8 --- /dev/null +++ b/test/libsolidity/syntaxTests/array/slice/storage_static.sol @@ -0,0 +1,8 @@ +contract C { + uint256[42] x; + function f() public view { + x[1:2]; + } +} +// ---- +// TypeError: (71-77): Index range access is only supported for dynamic calldata arrays. diff --git a/test/libsolidity/syntaxTests/parsing/array_range_and_ternary.sol b/test/libsolidity/syntaxTests/parsing/array_range_and_ternary.sol new file mode 100644 index 000000000000..36733898ebc5 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/array_range_and_ternary.sol @@ -0,0 +1,8 @@ +contract C { + function f(bool cond, bytes calldata x) external pure { + bytes1 a = x[cond ? 1 : 2]; a; + abi.decode(x[cond ? 1 : 2 : ], (uint256)); + abi.decode(x[cond ? 1 : 2 : cond ? 3 : 4], (uint256)); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/parsing/array_range_conversion.sol b/test/libsolidity/syntaxTests/parsing/array_range_conversion.sol new file mode 100644 index 000000000000..65595f17ba2f --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/array_range_conversion.sol @@ -0,0 +1,14 @@ +contract C { + function f() public pure { + uint[] memory x; + uint[1:](x); + uint[1:2](x); + uint[][1:](x); + } +} +// ---- +// TypeError: (77-85): Types cannot be sliced. +// TypeError: (77-88): Explicit type conversion not allowed from "uint256[] memory" to "uint256". +// TypeError: (98-107): Types cannot be sliced. +// TypeError: (98-110): Explicit type conversion not allowed from "uint256[] memory" to "uint256". +// TypeError: (120-130): Types cannot be sliced. diff --git a/test/libsolidity/syntaxTests/parsing/array_range_nested.sol b/test/libsolidity/syntaxTests/parsing/array_range_nested.sol new file mode 100644 index 000000000000..8c0b98e570d1 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/array_range_nested.sol @@ -0,0 +1,12 @@ +pragma experimental ABIEncoderV2; +contract C { + function f(uint256[][] calldata x) external pure { + x[0][1:2]; + x[1:2][1:2]; + uint256 a = x[1:2][1:2][1:][3:][0][2]; + uint256 b = x[1:][3:4][1][1:][2:3][0]; + a; b; + } +} +// ---- +// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/parsing/array_range_no_start.sol b/test/libsolidity/syntaxTests/parsing/array_range_no_start.sol new file mode 100644 index 000000000000..a0aba3e102a8 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/array_range_no_start.sol @@ -0,0 +1,6 @@ +contract C { + function f(uint256[] calldata x) external pure { + x[:][:10]; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/parsing/array_type_range.sol b/test/libsolidity/syntaxTests/parsing/array_type_range.sol new file mode 100644 index 000000000000..6f98e7efd6c0 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/array_type_range.sol @@ -0,0 +1,14 @@ +contract C { + function f() public pure { + uint[][1:] memory x; + uint[][1:2] memory x; + uint[1:] memory x; + uint[1:2] memory x; + } +} + +// ---- +// ParserError: (52-62): Expected array length expression. +// ParserError: (81-92): Expected array length expression. +// ParserError: (111-119): Expected array length expression. +// ParserError: (138-147): Expected array length expression. diff --git a/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_arg_type.sol b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_arg_type.sol index e418390c5fb7..ed1f07402502 100644 --- a/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_arg_type.sol +++ b/test/libsolidity/syntaxTests/specialFunctions/abidecode/abi_decode_invalid_arg_type.sol @@ -4,5 +4,5 @@ contract C { } } // ---- -// TypeError: (57-61): Invalid type for argument in function call. Invalid implicit conversion from type(uint256) to bytes memory requested. +// TypeError: (57-61): The first argument to "abi.decode" must be implicitly convertible to bytes memory or bytes calldata, but is of type type(uint256). // TypeError: (63-67): The second argument to "abi.decode" has to be a tuple of types. From d685554980f0ba2b7be20e6137a8db143f8b7aed Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Fri, 6 Sep 2019 19:11:07 +0200 Subject: [PATCH 026/283] Create option for metadata hash --- Changelog.md | 4 +- docs/metadata.rst | 54 +++--- docs/using-the-compiler.rst | 7 +- libsolidity/interface/CompilerStack.cpp | 24 ++- libsolidity/interface/CompilerStack.h | 12 ++ libsolidity/interface/StandardCompiler.cpp | 24 ++- libsolidity/interface/StandardCompiler.h | 1 + solc/CommandLineInterface.cpp | 38 ++++- solc/CommandLineInterface.h | 2 + test/Metadata.cpp | 8 +- test/libsolidity/GasCosts.cpp | 21 +-- test/libsolidity/Metadata.cpp | 154 ++++++++++++------ test/libsolidity/StandardCompiler.cpp | 4 +- test/libsolidity/gasTests/abiv2.sol | 4 +- test/libsolidity/gasTests/abiv2_optimised.sol | 4 +- test/libsolidity/gasTests/data_storage.sol | 4 +- test/libsolidity/gasTests/dispatch_large.sol | 4 +- .../gasTests/dispatch_large_optimised.sol | 4 +- test/libsolidity/gasTests/dispatch_medium.sol | 4 +- .../gasTests/dispatch_medium_optimised.sol | 6 +- test/libsolidity/gasTests/dispatch_small.sol | 4 +- .../gasTests/dispatch_small_optimised.sol | 4 +- 22 files changed, 273 insertions(+), 118 deletions(-) diff --git a/Changelog.md b/Changelog.md index 1151b3d7c8e7..229d720d5065 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,10 +4,12 @@ Breaking changes: * ABI: remove the deprecated ``constant`` and ``payable`` fields. * ABI: the ``type`` field is now required and no longer specified to default to ``function``. * Commandline interface: remove the text-based ast printer (``--ast``). + * Command line interface: Switch to the new error reporter by default. ``--old-reporter`` falls back to the deprecated old error reporter. + * Command line interface: Add option to disable or choose hash method between IPFS and Swarm for the bytecode metadata. * General: Disallow explicit conversions from external function types to ``address`` and add a member called ``address`` to them as replacement. * General: New reserved keywords: ``virtual``. + * Standard JSON Interface: Add option to disable or choose hash method between IPFS and Swarm for the bytecode metadata. * Type checker: Resulting type of exponentiation is equal to the type of the base. Also allow signed types for the base. - * Command line interface: Switch to the new error reporter by default. ``--old-reporter`` falls back to the deprecated old error reporter. Language Features: diff --git a/docs/metadata.rst b/docs/metadata.rst index 0250a06d1c0f..9da950231574 100644 --- a/docs/metadata.rst +++ b/docs/metadata.rst @@ -10,16 +10,18 @@ this file to query the compiler version, the sources used, the ABI and NatSpec documentation to more safely interact with the contract and verify its source code. -The compiler appends a Swarm hash of the metadata file to the end of the -bytecode (for details, see below) of each contract, so that you can retrieve -the file in an authenticated way without having to resort to a centralized -data provider. - -You have to publish the metadata file to Swarm (or another service) so that -others can access it. You create the file by using the ``solc --metadata`` +The compiler appends by default the IPFS hash of the metadata file to the end +of the bytecode (for details, see below) of each contract, so that you can +retrieve the file in an authenticated way without having to resort to a +centralized data provider. The other available options are the Swarm hash and +not appending the metadata hash to the bytecode. These can be configured via +the :ref:`Standard JSON Interface`. + +You have to publish the metadata file to IPFS, Swarm, or another service so +that others can access it. You create the file by using the ``solc --metadata`` command that generates a file called ``ContractName_meta.json``. It contains -Swarm references to the source code, so you have to upload all source files and -the metadata file. +IPFS and Swarm references to the source code, so you have to upload all source +files and the metadata file. The metadata file has the following format. The example below is presented in a human-readable way. Properly formatted metadata should use quotes correctly, @@ -86,7 +88,9 @@ explanatory purposes. }, metadata: { // Reflects the setting used in the input json, defaults to false - useLiteralContent: true + useLiteralContent: true, + // Reflects the setting used in the input json, defaults to "ipfs" + bytecodeHash: "ipfs" } // Required for Solidity: File and name of the contract or library this // metadata is created for. @@ -111,8 +115,8 @@ explanatory purposes. } .. warning:: - Since the bytecode of the resulting contract contains the metadata hash, any - change to the metadata results in a change of the bytecode. This includes + Since the bytecode of the resulting contract contains the metadata hash by default, any + change to the metadata might result in a change of the bytecode. This includes changes to a filename or path, and since the metadata includes a hash of all the sources used, a single whitespace change results in different metadata, and different bytecode. @@ -124,7 +128,7 @@ Encoding of the Metadata Hash in the Bytecode ============================================= Because we might support other ways to retrieve the metadata file in the future, -the mapping ``{"bzzr1": , "solc": }`` is stored +the mapping ``{"ipfs": , "solc": }`` is stored `CBOR `_-encoded. Since the mapping might contain more keys (see below) and the beginning of that encoding is not easy to find, its length is added in a two-byte big-endian @@ -132,12 +136,12 @@ encoding. The current version of the Solidity compiler usually adds the followin to the end of the deployed bytecode:: 0xa2 - 0x65 'b' 'z' 'z' 'r' '1' 0x58 0x20 <32 bytes swarm hash> + 0x64 'i' 'p' 'f' 's' 0x58 0x22 <34 bytes IPFS hash> 0x64 's' 'o' 'l' 'c' 0x43 <3 byte version encoding> 0x00 0x32 So in order to retrieve the data, the end of the deployed bytecode can be checked -to match that pattern and use the Swarm hash to retrieve the file. +to match that pattern and use the IPFS hash to retrieve the file. Whereas release builds of solc use a 3 byte encoding of the version as shown above (one byte each for major, minor and patch version number), prerelease builds @@ -145,25 +149,25 @@ will instead use a complete version string including commit hash and build date. .. note:: The CBOR mapping can also contain other keys, so it is better to fully - decode the data instead of relying on it starting with ``0xa265``. + decode the data instead of relying on it starting with ``0xa264``. For example, if any experimental features that affect code generation are used, the mapping will also contain ``"experimental": true``. .. note:: - The compiler currently uses the "swarm version 1" hash of the metadata, - but this might change in the future, so do not rely on this sequence - to start with ``0xa2 0x65 'b' 'z' 'z' 'r' '1'``. We might also - add additional data to this CBOR structure, so the - best option is to use a proper CBOR parser. + The compiler currently uses the IPFS hash of the metadata by default, but + it may also use the bzzr1 hash or some other hash in the future, so do + not rely on this sequence to start with ``0xa2 0x64 'i' 'p' 'f' 's'``. We + might also add additional data to this CBOR structure, so the best option + is to use a proper CBOR parser. Usage for Automatic Interface Generation and NatSpec ==================================================== The metadata is used in the following way: A component that wants to interact -with a contract (e.g. Mist or any wallet) retrieves the code of the contract, from that -the Swarm hash of a file which is then retrieved. -That file is JSON-decoded into a structure like above. +with a contract (e.g. Mist or any wallet) retrieves the code of the contract, +from that the IPFS/Swarm hash of a file which is then retrieved. That file +is JSON-decoded into a structure like above. The component can then use the ABI to automatically generate a rudimentary user interface for the contract. @@ -177,7 +181,7 @@ For additional information, read :doc:`Ethereum Natural Language Specification ( Usage for Source Code Verification ================================== -In order to verify the compilation, sources can be retrieved from Swarm +In order to verify the compilation, sources can be retrieved from IPFS/Swarm via the link in the metadata file. The compiler of the correct version (which is checked to be part of the "official" compilers) is invoked on that input with the specified settings. The resulting diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index b8c518bc5d7a..8e27fd133e39 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -236,7 +236,12 @@ Input Description // Metadata settings (optional) "metadata": { // Use only literal content and not URLs (false by default) - "useLiteralContent": true + "useLiteralContent": true, + // Use the given hash method for the metadata hash that is appended to the bytecode. + // The metadata hash can be removed from the bytecode via option "none". + // The other options are "ipfs" and "bzzr1". + // If the option is omitted, "ipfs" is used by default. + "bytecodeHash": "ipfs" }, // Addresses of the libraries. If not all libraries are given here, // it can result in unlinked objects whose output data is different. diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index f3c8ffa15b1e..539cca48e423 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -159,6 +159,13 @@ void CompilerStack::useMetadataLiteralSources(bool _metadataLiteralSources) m_metadataLiteralSources = _metadataLiteralSources; } +void CompilerStack::setMetadataHash(MetadataHash _metadataHash) +{ + if (m_stackState >= ParsingPerformed) + BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set metadata hash before parsing.")); + m_metadataHash = _metadataHash; +} + void CompilerStack::addSMTLib2Response(h256 const& _hash, string const& _response) { if (m_stackState >= ParsingPerformed) @@ -182,6 +189,7 @@ void CompilerStack::reset(bool _keepSettings) m_generateEWasm = false; m_optimiserSettings = OptimiserSettings::minimal(); m_metadataLiteralSources = false; + m_metadataHash = MetadataHash::IPFS; } m_globalContext.reset(); m_scopes.clear(); @@ -1155,6 +1163,10 @@ string CompilerStack::createMetadata(Contract const& _contract) const if (m_metadataLiteralSources) meta["settings"]["metadata"]["useLiteralContent"] = true; + + static vector hashes{"ipfs", "bzzr1", "none"}; + meta["settings"]["metadata"]["bytecodeHash"] = hashes.at(unsigned(m_metadataHash)); + meta["settings"]["evmVersion"] = m_evmVersion.name(); meta["settings"]["compilationTarget"][_contract.contract->sourceUnitName()] = _contract.contract->annotation().canonicalName; @@ -1263,7 +1275,17 @@ class MetadataCBOREncoder bytes CompilerStack::createCBORMetadata(string const& _metadata, bool _experimentalMode) { MetadataCBOREncoder encoder; - encoder.pushBytes("bzzr1", dev::bzzr1Hash(_metadata).asBytes()); + + if (m_metadataHash == MetadataHash::IPFS) + { + solAssert(_metadata.length() < 1024 * 256, "Metadata too large."); + encoder.pushBytes("ipfs", dev::ipfsHash(_metadata)); + } + else if (m_metadataHash == MetadataHash::Bzzr1) + encoder.pushBytes("bzzr1", dev::bzzr1Hash(_metadata).asBytes()); + else + solAssert(m_metadataHash == MetadataHash::None, "Invalid metadata hash"); + if (_experimentalMode) encoder.pushBool("experimental", true); if (m_release) diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 72a81b4372a1..11fb960a3ea8 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -92,6 +92,12 @@ class CompilerStack: boost::noncopyable CompilationSuccessful }; + enum class MetadataHash { + IPFS, + Bzzr1, + None + }; + struct Remapping { std::string context; @@ -171,6 +177,11 @@ class CompilerStack: boost::noncopyable /// Must be set before parsing. void useMetadataLiteralSources(bool _metadataLiteralSources); + /// Sets whether and which hash should be used + /// to store the metadata in the bytecode. + /// @param _metadataHash can be IPFS, Bzzr1, None + void setMetadataHash(MetadataHash _metadataHash); + /// Sets the sources. Must be set before parsing. void setSources(StringMap _sources); @@ -418,6 +429,7 @@ class CompilerStack: boost::noncopyable langutil::ErrorList m_errorList; langutil::ErrorReporter m_errorReporter; bool m_metadataLiteralSources = false; + MetadataHash m_metadataHash = MetadataHash::IPFS; bool m_parserErrorRecovery = false; State m_stackState = Empty; /// Whether or not there has been an error during processing. diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index ca27deac22a5..c954b8a3d24b 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -378,9 +378,16 @@ boost::optional checkOptimizerDetail(Json::Value const& _details, s boost::optional checkMetadataKeys(Json::Value const& _input) { - if (_input.isObject() && _input.isMember("useLiteralContent") && !_input["useLiteralContent"].isBool()) - return formatFatalError("JSONError", "\"settings.metadata.useLiteralContent\" must be Boolean"); - static set keys{"useLiteralContent"}; + if (_input.isObject()) + { + if (_input.isMember("useLiteralContent") && !_input["useLiteralContent"].isBool()) + return formatFatalError("JSONError", "\"settings.metadata.useLiteralContent\" must be Boolean"); + + static set hashes{"ipfs", "bzzr1", "none"}; + if (_input.isMember("bytecodeHash") && !hashes.count(_input["bytecodeHash"].asString())) + return formatFatalError("JSONError", "\"settings.metadata.bytecodeHash\" must be \"ipfs\", \"bzzr1\" or \"none\""); + } + static set keys{"useLiteralContent", "bytecodeHash"}; return checkKeys(_input, keys, "settings.metadata"); } @@ -710,6 +717,16 @@ boost::variant StandardCompile return *result; ret.metadataLiteralSources = metadataSettings.get("useLiteralContent", Json::Value(false)).asBool(); + if (metadataSettings.isMember("bytecodeHash")) + { + auto metadataHash = metadataSettings["bytecodeHash"].asString(); + ret.metadataHash = + metadataHash == "ipfs" ? + CompilerStack::MetadataHash::IPFS : + metadataHash == "bzzr1" ? + CompilerStack::MetadataHash::Bzzr1 : + CompilerStack::MetadataHash::None; + } Json::Value outputSelection = settings.get("outputSelection", Json::Value()); @@ -735,6 +752,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting compilerStack.setOptimiserSettings(std::move(_inputsAndSettings.optimiserSettings)); compilerStack.setLibraries(_inputsAndSettings.libraries); compilerStack.useMetadataLiteralSources(_inputsAndSettings.metadataLiteralSources); + compilerStack.setMetadataHash(_inputsAndSettings.metadataHash); compilerStack.setRequestedContractNames(requestedContractNames(_inputsAndSettings.outputSelection)); compilerStack.enableIRGeneration(isIRRequested(_inputsAndSettings.outputSelection)); diff --git a/libsolidity/interface/StandardCompiler.h b/libsolidity/interface/StandardCompiler.h index 9d0320abb8bc..e5562cd2f30d 100644 --- a/libsolidity/interface/StandardCompiler.h +++ b/libsolidity/interface/StandardCompiler.h @@ -68,6 +68,7 @@ class StandardCompiler: boost::noncopyable OptimiserSettings optimiserSettings = OptimiserSettings::minimal(); std::map libraries; bool metadataLiteralSources = false; + CompilerStack::MetadataHash metadataHash = CompilerStack::MetadataHash::IPFS; Json::Value outputSelection; }; diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index a061fc3d916c..19883d5bd472 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -122,15 +122,18 @@ static string const g_strInputFile = "input-file"; static string const g_strInterface = "interface"; static string const g_strYul = "yul"; static string const g_strIR = "ir"; +static string const g_strIPFS = "ipfs"; static string const g_strEWasm = "ewasm"; static string const g_strLicense = "license"; static string const g_strLibraries = "libraries"; static string const g_strLink = "link"; static string const g_strMachine = "machine"; static string const g_strMetadata = "metadata"; +static string const g_strMetadataHash = "metadata-hash"; static string const g_strMetadataLiteral = "metadata-literal"; static string const g_strNatspecDev = "devdoc"; static string const g_strNatspecUser = "userdoc"; +static string const g_strNone = "none"; static string const g_strOpcodes = "opcodes"; static string const g_strOptimize = "optimize"; static string const g_strOptimizeRuns = "optimize-runs"; @@ -144,6 +147,7 @@ static string const g_strSrcMap = "srcmap"; static string const g_strSrcMapRuntime = "srcmap-runtime"; static string const g_strStandardJSON = "standard-json"; static string const g_strStrictAssembly = "strict-assembly"; +static string const g_strSwarm = "swarm"; static string const g_strPrettyJson = "pretty-json"; static string const g_strVersion = "version"; static string const g_strIgnoreMissingFiles = "ignore-missing"; @@ -174,6 +178,7 @@ static string const g_argLibraries = g_strLibraries; static string const g_argLink = g_strLink; static string const g_argMachine = g_strMachine; static string const g_argMetadata = g_strMetadata; +static string const g_argMetadataHash = g_strMetadataHash; static string const g_argMetadataLiteral = g_strMetadataLiteral; static string const g_argNatspecDev = g_strNatspecDev; static string const g_argNatspecUser = g_strNatspecUser; @@ -218,6 +223,14 @@ static set const g_machineArgs g_streWasm }; +/// Possible arguments to for --metadata-hash +static set const g_metadataHashArgs +{ + g_strIPFS, + g_strSwarm, + g_strNone +}; + static void version() { sout() << @@ -696,7 +709,12 @@ Allowed options)", "Switch to linker mode, ignoring all options apart from --libraries " "and modify binaries in place." ) - (g_argMetadataLiteral.c_str(), "Store referenced sources are literal data in the metadata output.") + ( + g_argMetadataHash.c_str(), + po::value()->value_name(boost::join(g_metadataHashArgs, ",")), + "Choose hash method for the bytecode metadata or disable it." + ) + (g_argMetadataLiteral.c_str(), "Store referenced sources as literal data in the metadata output.") ( g_argAllowPaths.c_str(), po::value()->value_name("path(s)"), @@ -923,6 +941,22 @@ bool CommandLineInterface::processInput() return link(); } + if (m_args.count(g_argMetadataHash)) + { + string hashStr = m_args[g_argMetadataHash].as(); + if (hashStr == g_strIPFS) + m_metadataHash = CompilerStack::MetadataHash::IPFS; + else if (hashStr == g_strSwarm) + m_metadataHash = CompilerStack::MetadataHash::Bzzr1; + else if (hashStr == g_strNone) + m_metadataHash = CompilerStack::MetadataHash::None; + else + { + serr() << "Invalid option for --metadata-hash: " << hashStr << endl; + return false; + } + } + m_compiler.reset(new CompilerStack(fileReader)); unique_ptr formatter; @@ -935,6 +969,8 @@ bool CommandLineInterface::processInput() { if (m_args.count(g_argMetadataLiteral) > 0) m_compiler->useMetadataLiteralSources(true); + if (m_args.count(g_argMetadataHash)) + m_compiler->setMetadataHash(m_metadataHash); if (m_args.count(g_argInputFile)) m_compiler->setRemappings(m_remappings); m_compiler->setSources(m_sourceCodes); diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index cdcc5063b7e6..87ac8efd8e38 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -111,6 +111,8 @@ class CommandLineInterface std::unique_ptr m_compiler; /// EVM version to use langutil::EVMVersion m_evmVersion; + /// Chosen hash method for the bytecode metadata. + CompilerStack::MetadataHash m_metadataHash = CompilerStack::MetadataHash::IPFS; /// Whether or not to colorize diagnostics output. bool m_coloredOutput = true; }; diff --git a/test/Metadata.cpp b/test/Metadata.cpp index bdbf427e9e66..d8a593b79e5e 100644 --- a/test/Metadata.cpp +++ b/test/Metadata.cpp @@ -41,9 +41,9 @@ bytes onlyMetadata(bytes const& _bytecode) size_t metadataSize = (_bytecode[size - 2] << 8) + _bytecode[size - 1]; if (size < (metadataSize + 2)) return bytes{}; - // Sanity check: assume the first byte is a fixed-size CBOR array with either 2 or 3 entries + // Sanity check: assume the first byte is a fixed-size CBOR array with 1, 2 or 3 entries unsigned char firstByte = _bytecode[size - metadataSize - 2]; - if (firstByte != 0xa2 && firstByte != 0xa3) + if (firstByte != 0xa1 && firstByte != 0xa2 && firstByte != 0xa3) return bytes{}; return bytes(_bytecode.end() - metadataSize - 2, _bytecode.end() - 2); } @@ -185,7 +185,9 @@ bool isValidMetadata(string const& _metadata) !metadata.isMember("settings") || !metadata.isMember("sources") || !metadata.isMember("output") || - !metadata["settings"].isMember("evmVersion") + !metadata["settings"].isMember("evmVersion") || + !metadata["settings"].isMember("metadata") || + !metadata["settings"]["metadata"].isMember("bytecodeHash") ) return false; diff --git a/test/libsolidity/GasCosts.cpp b/test/libsolidity/GasCosts.cpp index 8aad4fab79dd..977553286a6a 100644 --- a/test/libsolidity/GasCosts.cpp +++ b/test/libsolidity/GasCosts.cpp @@ -19,7 +19,7 @@ */ #include -#include +#include #include #include @@ -40,18 +40,18 @@ namespace test #define CHECK_DEPLOY_GAS(_gasNoOpt, _gasOpt) \ do \ { \ - u256 bzzr1Cost = GasMeter::dataGas(dev::bzzr1Hash(m_compiler.metadata(m_compiler.lastContractName())).asBytes(), true); \ + u256 ipfsCost = GasMeter::dataGas(dev::ipfsHash(m_compiler.metadata(m_compiler.lastContractName())), true); \ u256 gasOpt{_gasOpt}; \ u256 gasNoOpt{_gasNoOpt}; \ u256 gas = m_optimiserSettings == OptimiserSettings::minimal() ? gasNoOpt : gasOpt; \ BOOST_CHECK_MESSAGE( \ - m_gasUsed >= bzzr1Cost, \ + m_gasUsed >= ipfsCost, \ "Gas used: " + \ m_gasUsed.str() + \ - " is less than the data cost for the bzzr1 hash: " + \ - u256(bzzr1Cost).str() \ + " is less than the data cost for the IPFS hash: " + \ + u256(ipfsCost).str() \ ); \ - u256 gasUsed = m_gasUsed - bzzr1Cost; \ + u256 gasUsed = m_gasUsed - ipfsCost; \ BOOST_CHECK_MESSAGE( \ gas == gasUsed, \ "Gas used: " + \ @@ -96,17 +96,18 @@ BOOST_AUTO_TEST_CASE(string_storage) compileAndRun(sourceCode); if (Options::get().evmVersion() <= EVMVersion::byzantium()) - CHECK_DEPLOY_GAS(134071, 130763); + CHECK_DEPLOY_GAS(134209, 130895); // This is only correct on >=Constantinople. else if (Options::get().useABIEncoderV2) { if (Options::get().optimizeYul) - CHECK_DEPLOY_GAS(151455, 127653); + CHECK_DEPLOY_GAS(127785, 127785); else - CHECK_DEPLOY_GAS(151455, 135371); + CHECK_DEPLOY_GAS(151587, 135371); } else - CHECK_DEPLOY_GAS(126861, 119591); + CHECK_DEPLOY_GAS(126993, 119723); + if (Options::get().evmVersion() >= EVMVersion::byzantium()) { callContractFunction("f()"); diff --git a/test/libsolidity/Metadata.cpp b/test/libsolidity/Metadata.cpp index 89093e035db7..a4463ce0f3d3 100644 --- a/test/libsolidity/Metadata.cpp +++ b/test/libsolidity/Metadata.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include using namespace std; @@ -60,28 +61,54 @@ BOOST_AUTO_TEST_CASE(metadata_stamp) } )"; for (auto release: std::set{true, VersionIsRelease}) - { - CompilerStack compilerStack; - compilerStack.overwriteReleaseFlag(release); - compilerStack.setSources({{"", std::string(sourceCode)}}); - compilerStack.setEVMVersion(dev::test::Options::get().evmVersion()); - compilerStack.setOptimiserSettings(dev::test::Options::get().optimize); - BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); - bytes const& bytecode = compilerStack.runtimeObject("test").bytecode; - std::string const& metadata = compilerStack.metadata("test"); - BOOST_CHECK(dev::test::isValidMetadata(metadata)); - bytes hash = dev::bzzr1Hash(metadata).asBytes(); - BOOST_REQUIRE(hash.size() == 32); - auto const cborMetadata = requireParsedCBORMetadata(bytecode); - BOOST_CHECK(cborMetadata.size() == 2); - BOOST_CHECK(cborMetadata.count("solc") == 1); - if (release) - BOOST_CHECK(cborMetadata.at("solc") == toHex(VersionCompactBytes)); - else - BOOST_CHECK(cborMetadata.at("solc") == VersionStringStrict); - BOOST_CHECK(cborMetadata.count("bzzr1") == 1); - BOOST_CHECK(cborMetadata.at("bzzr1") == toHex(hash)); - } + for (auto metadataHash: set{ + CompilerStack::MetadataHash::IPFS, + CompilerStack::MetadataHash::Bzzr1, + CompilerStack::MetadataHash::None + }) + { + CompilerStack compilerStack; + compilerStack.overwriteReleaseFlag(release); + compilerStack.setSources({{"", std::string(sourceCode)}}); + compilerStack.setEVMVersion(dev::test::Options::get().evmVersion()); + compilerStack.setOptimiserSettings(dev::test::Options::get().optimize); + compilerStack.setMetadataHash(metadataHash); + BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); + bytes const& bytecode = compilerStack.runtimeObject("test").bytecode; + std::string const& metadata = compilerStack.metadata("test"); + BOOST_CHECK(dev::test::isValidMetadata(metadata)); + + auto const cborMetadata = requireParsedCBORMetadata(bytecode); + if (metadataHash == CompilerStack::MetadataHash::None) + BOOST_CHECK(cborMetadata.size() == 1); + else + { + bytes hash; + string hashMethod; + if (metadataHash == CompilerStack::MetadataHash::IPFS) + { + hash = dev::ipfsHash(metadata); + BOOST_REQUIRE(hash.size() == 34); + hashMethod = "ipfs"; + } + else + { + hash = dev::bzzr1Hash(metadata).asBytes(); + BOOST_REQUIRE(hash.size() == 32); + hashMethod = "bzzr1"; + } + + BOOST_CHECK(cborMetadata.size() == 2); + BOOST_CHECK(cborMetadata.count(hashMethod) == 1); + BOOST_CHECK(cborMetadata.at(hashMethod) == toHex(hash)); + } + + BOOST_CHECK(cborMetadata.count("solc") == 1); + if (release) + BOOST_CHECK(cborMetadata.at("solc") == toHex(VersionCompactBytes)); + else + BOOST_CHECK(cborMetadata.at("solc") == VersionStringStrict); + } } BOOST_AUTO_TEST_CASE(metadata_stamp_experimental) @@ -94,31 +121,57 @@ BOOST_AUTO_TEST_CASE(metadata_stamp_experimental) function g(function(uint) external returns (uint) x) public {} } )"; - for(auto release: std::set{true, VersionIsRelease}) - { - CompilerStack compilerStack; - compilerStack.overwriteReleaseFlag(release); - compilerStack.setSources({{"", std::string(sourceCode)}}); - compilerStack.setEVMVersion(dev::test::Options::get().evmVersion()); - compilerStack.setOptimiserSettings(dev::test::Options::get().optimize); - BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); - bytes const& bytecode = compilerStack.runtimeObject("test").bytecode; - std::string const& metadata = compilerStack.metadata("test"); - BOOST_CHECK(dev::test::isValidMetadata(metadata)); - bytes hash = dev::bzzr1Hash(metadata).asBytes(); - BOOST_REQUIRE(hash.size() == 32); - auto const cborMetadata = requireParsedCBORMetadata(bytecode); - BOOST_CHECK(cborMetadata.size() == 3); - BOOST_CHECK(cborMetadata.count("solc") == 1); - if (release) - BOOST_CHECK(cborMetadata.at("solc") == toHex(VersionCompactBytes)); - else - BOOST_CHECK(cborMetadata.at("solc") == VersionStringStrict); - BOOST_CHECK(cborMetadata.count("bzzr1") == 1); - BOOST_CHECK(cborMetadata.at("bzzr1") == toHex(hash)); - BOOST_CHECK(cborMetadata.count("experimental") == 1); - BOOST_CHECK(cborMetadata.at("experimental") == "true"); - } + for (auto release: set{true, VersionIsRelease}) + for (auto metadataHash: set{ + CompilerStack::MetadataHash::IPFS, + CompilerStack::MetadataHash::Bzzr1, + CompilerStack::MetadataHash::None + }) + { + CompilerStack compilerStack; + compilerStack.overwriteReleaseFlag(release); + compilerStack.setSources({{"", std::string(sourceCode)}}); + compilerStack.setEVMVersion(dev::test::Options::get().evmVersion()); + compilerStack.setOptimiserSettings(dev::test::Options::get().optimize); + compilerStack.setMetadataHash(metadataHash); + BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); + bytes const& bytecode = compilerStack.runtimeObject("test").bytecode; + std::string const& metadata = compilerStack.metadata("test"); + BOOST_CHECK(dev::test::isValidMetadata(metadata)); + + auto const cborMetadata = requireParsedCBORMetadata(bytecode); + if (metadataHash == CompilerStack::MetadataHash::None) + BOOST_CHECK(cborMetadata.size() == 2); + else + { + bytes hash; + string hashMethod; + if (metadataHash == CompilerStack::MetadataHash::IPFS) + { + hash = dev::ipfsHash(metadata); + BOOST_REQUIRE(hash.size() == 34); + hashMethod = "ipfs"; + } + else + { + hash = dev::bzzr1Hash(metadata).asBytes(); + BOOST_REQUIRE(hash.size() == 32); + hashMethod = "bzzr1"; + } + + BOOST_CHECK(cborMetadata.size() == 3); + BOOST_CHECK(cborMetadata.count(hashMethod) == 1); + BOOST_CHECK(cborMetadata.at(hashMethod) == toHex(hash)); + } + + BOOST_CHECK(cborMetadata.count("solc") == 1); + if (release) + BOOST_CHECK(cborMetadata.at("solc") == toHex(VersionCompactBytes)); + else + BOOST_CHECK(cborMetadata.at("solc") == VersionStringStrict); + BOOST_CHECK(cborMetadata.count("experimental") == 1); + BOOST_CHECK(cborMetadata.at("experimental") == "true"); + } } BOOST_AUTO_TEST_CASE(metadata_relevant_sources) @@ -218,16 +271,13 @@ BOOST_AUTO_TEST_CASE(metadata_useLiteralContent) jsonParse(metadata_str, metadata); BOOST_CHECK(dev::test::isValidMetadata(metadata_str)); BOOST_CHECK(metadata.isMember("settings")); + BOOST_CHECK(metadata["settings"].isMember("metadata")); + BOOST_CHECK(metadata["settings"]["metadata"].isMember("bytecodeHash")); if (_literal) { - BOOST_CHECK(metadata["settings"].isMember("metadata")); BOOST_CHECK(metadata["settings"]["metadata"].isMember("useLiteralContent")); BOOST_CHECK(metadata["settings"]["metadata"]["useLiteralContent"].asBool()); } - else - { - BOOST_CHECK(!metadata["settings"].isMember("metadata")); - } }; check(sourceCode, true); diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 336455fd2046..aef8ee3c1cdc 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -364,7 +364,7 @@ BOOST_AUTO_TEST_CASE(basic_compilation) BOOST_CHECK_EQUAL( dev::test::bytecodeSansMetadata(contract["evm"]["bytecode"]["object"].asString()), string("6080604052348015600f57600080fd5b5060") + - (VersionIsRelease ? "3e" : toHex(bytes{uint8_t(60 + VersionStringStrict.size())})) + + (VersionIsRelease ? "3f" : toHex(bytes{uint8_t(61 + VersionStringStrict.size())})) + "80601d6000396000f3fe6080604052600080fdfe" ); BOOST_CHECK(contract["evm"]["assembly"].isString()); @@ -377,7 +377,7 @@ BOOST_AUTO_TEST_CASE(basic_compilation) "tag_1:\n /* \"fileA\":0:14 contract A { } */\n pop\n dataSize(sub_0)\n dup1\n " "dataOffset(sub_0)\n 0x00\n codecopy\n 0x00\n return\nstop\n\nsub_0: assembly {\n " "/* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x80)\n 0x00\n " - "dup1\n revert\n\n auxdata: 0xa265627a7a72315820" + "dup1\n revert\n\n auxdata: 0xa26469706673582212" ) == 0); BOOST_CHECK(contract["evm"]["gasEstimates"].isObject()); BOOST_CHECK_EQUAL(contract["evm"]["gasEstimates"].size(), 1); diff --git a/test/libsolidity/gasTests/abiv2.sol b/test/libsolidity/gasTests/abiv2.sol index 2ee698008e3b..80a7c6327605 100644 --- a/test/libsolidity/gasTests/abiv2.sol +++ b/test/libsolidity/gasTests/abiv2.sol @@ -14,9 +14,9 @@ contract C { } // ---- // creation: -// codeDepositCost: 1122600 +// codeDepositCost: 1122800 // executionCost: 1167 -// totalCost: 1123767 +// totalCost: 1123967 // external: // a(): 530 // b(uint256): infinite diff --git a/test/libsolidity/gasTests/abiv2_optimised.sol b/test/libsolidity/gasTests/abiv2_optimised.sol index f225763808a0..d167e7d3c275 100644 --- a/test/libsolidity/gasTests/abiv2_optimised.sol +++ b/test/libsolidity/gasTests/abiv2_optimised.sol @@ -17,9 +17,9 @@ contract C { // optimize-yul: true // ---- // creation: -// codeDepositCost: 624200 +// codeDepositCost: 624400 // executionCost: 657 -// totalCost: 624857 +// totalCost: 625057 // external: // a(): 429 // b(uint256): 884 diff --git a/test/libsolidity/gasTests/data_storage.sol b/test/libsolidity/gasTests/data_storage.sol index 5efa87d57331..29cade28c8fa 100644 --- a/test/libsolidity/gasTests/data_storage.sol +++ b/test/libsolidity/gasTests/data_storage.sol @@ -13,8 +13,8 @@ contract C { } // ---- // creation: -// codeDepositCost: 256800 +// codeDepositCost: 257000 // executionCost: 300 -// totalCost: 257100 +// totalCost: 257300 // external: // f(): 252 diff --git a/test/libsolidity/gasTests/dispatch_large.sol b/test/libsolidity/gasTests/dispatch_large.sol index 7fc28339c963..7cb873710819 100644 --- a/test/libsolidity/gasTests/dispatch_large.sol +++ b/test/libsolidity/gasTests/dispatch_large.sol @@ -24,9 +24,9 @@ contract Large { } // ---- // creation: -// codeDepositCost: 636800 +// codeDepositCost: 637000 // executionCost: 670 -// totalCost: 637470 +// totalCost: 637670 // external: // a(): 451 // b(uint256): 846 diff --git a/test/libsolidity/gasTests/dispatch_large_optimised.sol b/test/libsolidity/gasTests/dispatch_large_optimised.sol index cee223b4cdf3..4f6f238adce7 100644 --- a/test/libsolidity/gasTests/dispatch_large_optimised.sol +++ b/test/libsolidity/gasTests/dispatch_large_optimised.sol @@ -27,9 +27,9 @@ contract Large { // optimize-runs: 2 // ---- // creation: -// codeDepositCost: 260400 +// codeDepositCost: 260600 // executionCost: 300 -// totalCost: 260700 +// totalCost: 260900 // external: // a(): 398 // b(uint256): 1105 diff --git a/test/libsolidity/gasTests/dispatch_medium.sol b/test/libsolidity/gasTests/dispatch_medium.sol index 0c1d8012662b..9a3b4835ca0a 100644 --- a/test/libsolidity/gasTests/dispatch_medium.sol +++ b/test/libsolidity/gasTests/dispatch_medium.sol @@ -11,9 +11,9 @@ contract Medium { } // ---- // creation: -// codeDepositCost: 253000 +// codeDepositCost: 253200 // executionCost: 294 -// totalCost: 253294 +// totalCost: 253494 // external: // a(): 428 // b(uint256): 846 diff --git a/test/libsolidity/gasTests/dispatch_medium_optimised.sol b/test/libsolidity/gasTests/dispatch_medium_optimised.sol index b2c76140a802..44b4a72e0993 100644 --- a/test/libsolidity/gasTests/dispatch_medium_optimised.sol +++ b/test/libsolidity/gasTests/dispatch_medium_optimised.sol @@ -14,9 +14,9 @@ contract Medium { // optimize-runs: 2 // ---- // creation: -// codeDepositCost: 140800 -// executionCost: 183 -// totalCost: 140983 +// codeDepositCost: 141000 +// executionCost: 190 +// totalCost: 141190 // external: // a(): 398 // b(uint256): 863 diff --git a/test/libsolidity/gasTests/dispatch_small.sol b/test/libsolidity/gasTests/dispatch_small.sol index cb163d1ba539..87634ac73b79 100644 --- a/test/libsolidity/gasTests/dispatch_small.sol +++ b/test/libsolidity/gasTests/dispatch_small.sol @@ -6,9 +6,9 @@ contract Small { } // ---- // creation: -// codeDepositCost: 83600 +// codeDepositCost: 83800 // executionCost: 135 -// totalCost: 83735 +// totalCost: 83935 // external: // fallback: 118 // a(): 383 diff --git a/test/libsolidity/gasTests/dispatch_small_optimised.sol b/test/libsolidity/gasTests/dispatch_small_optimised.sol index 7153a784c766..487f2c9d985c 100644 --- a/test/libsolidity/gasTests/dispatch_small_optimised.sol +++ b/test/libsolidity/gasTests/dispatch_small_optimised.sol @@ -9,9 +9,9 @@ contract Small { // optimize-runs: 2 // ---- // creation: -// codeDepositCost: 60400 +// codeDepositCost: 60600 // executionCost: 111 -// totalCost: 60511 +// totalCost: 60711 // external: // fallback: 118 // a(): 376 From 0567643323e683081457f3f5c1add2f77d44c45e Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 16 Sep 2019 19:06:50 +0200 Subject: [PATCH 027/283] Disable style check. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index d5a5f67af6aa..7af33d3fffb5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -613,7 +613,7 @@ workflows: # basic checks - chk_spelling: *workflow_trigger_on_tags - chk_coding_style: *workflow_trigger_on_tags - - chk_docs_examples: *workflow_trigger_on_tags + # DISABLED FOR 0.6.0 - chk_docs_examples: *workflow_trigger_on_tags - chk_buglist: *workflow_trigger_on_tags - chk_proofs: *workflow_trigger_on_tags From 43d6e00b143f9f2fd83fbca3ab4bbd1d3b33bf83 Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Sat, 14 Sep 2019 00:54:51 +0200 Subject: [PATCH 028/283] Add push() for dynamic storage arrays --- Changelog.md | 3 + docs/060-breaking-changes.rst | 5 + docs/types/reference-types.rst | 12 ++- libsolidity/analysis/TypeChecker.cpp | 13 ++- libsolidity/ast/Types.cpp | 9 +- libsolidity/codegen/ExpressionCompiler.cpp | 93 ++++++++++++------- test/compilationTests/corion/schelling.sol | 3 +- test/libsolidity/SolidityEndToEndTest.cpp | 18 ++-- .../semanticTests/array/push_no_args_1d.sol | 32 +++++++ .../semanticTests/array/push_no_args_2d.sol | 39 ++++++++ .../array/push_no_args_bytes.sol | 28 ++++++ .../array/push_no_args_struct.sol | 44 +++++++++ 12 files changed, 251 insertions(+), 48 deletions(-) create mode 100644 test/libsolidity/semanticTests/array/push_no_args_1d.sol create mode 100644 test/libsolidity/semanticTests/array/push_no_args_2d.sol create mode 100644 test/libsolidity/semanticTests/array/push_no_args_bytes.sol create mode 100644 test/libsolidity/semanticTests/array/push_no_args_struct.sol diff --git a/Changelog.md b/Changelog.md index 680a02c08e55..45bc06e5e452 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ Breaking changes: * General: Disallow explicit conversions from external function types to ``address`` and add a member called ``address`` to them as replacement. * General: New reserved keywords: ``virtual``. * Standard JSON Interface: Add option to disable or choose hash method between IPFS and Swarm for the bytecode metadata. + * Syntax: ``push(element)`` for dynamic storage arrays do not return the new length anymore. * Type checker: Resulting type of exponentiation is equal to the type of the base. Also allow signed types for the base. @@ -17,6 +18,8 @@ Language Features: * Allow underscores as delimiters in hex strings. * Allow explicit conversions from ``address`` to ``address payable`` via ``payable(...)``. * Introduce syntax for array slices and implement them for dynamic calldata arrays. + * Introduce ``push()`` for dynamic storage arrays. It returns a reference to the newly allocated element, if applicable. + * Modify ``push(element)`` for dynamic storage arrays such that it does not return the new length anymore. Compiler Features: diff --git a/docs/060-breaking-changes.rst b/docs/060-breaking-changes.rst index 79cc268deafa..effa966f9823 100644 --- a/docs/060-breaking-changes.rst +++ b/docs/060-breaking-changes.rst @@ -19,6 +19,8 @@ This section lists purely syntactic changes that do not affect the behavior of e * Conversions from ``address`` to ``address payable`` are now possible via ``payable(x)``, where ``x`` must be of type ``address``. +* Function ``push(value)`` for dynamic storage arrays do not return the new length anymore. + * New reserved keywords: ``virtual``. Semantic Only Changes @@ -45,6 +47,9 @@ This section gives detailed instructions on how to update prior code for every b * Change ``address(f)`` to ``f.address`` for ``f`` being of external function type. +* Change ``uint length = array.push(value)`` to ``array.push(value);``. The new length can be + accessed via ``array.length``. + Deprecated Elements =================== diff --git a/docs/types/reference-types.rst b/docs/types/reference-types.rst index de1e5f543fb8..ed565f80a1e6 100644 --- a/docs/types/reference-types.rst +++ b/docs/types/reference-types.rst @@ -109,8 +109,9 @@ restrictions for types apply, in that mappings can only be stored in the It is possible to mark state variable arrays ``public`` and have Solidity create a :ref:`getter `. The numeric index becomes a required parameter for the getter. -Accessing an array past its end causes a failing assertion. You can use the ``.push()`` method to append a new element at the end or assign to the ``.length`` :ref:`member ` to change the size (see below for caveats). -method or increase the ``.length`` :ref:`member ` to add elements. +Accessing an array past its end causes a failing assertion. Methods ``.push()`` and ``.push(value)`` can be used +to append a new element at the end of the array, where ``.push()`` appends a zero-initialized element and returns +a reference to it. ``bytes`` and ``strings`` as Arrays ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -221,7 +222,9 @@ Array Members removed elements. If you try to resize a non-dynamic array that isn't in storage, you receive a ``Value must be an lvalue`` error. **push**: - Dynamic storage arrays and ``bytes`` (not ``string``) have a member function called ``push`` that you can use to append an element at the end of the array. The element will be zero-initialised. The function returns the new length. + Dynamic storage arrays and ``bytes`` (not ``string``) have a member function called ``push`` that you can use to append an element at the end of the array. + If no argument is given, the element will be zero-initialised and a reference to the new element is returned. + If a value is given as argument, ``push`` returns nothing. **pop**: Dynamic storage arrays and ``bytes`` (not ``string``) have a member function called ``pop`` that you can use to remove an element from the end of the array. This also implicitly calls :ref:`delete` on the removed element. @@ -315,7 +318,8 @@ Array Members } function addFlag(bool[2] memory flag) public returns (uint) { - return m_pairsOfFlags.push(flag); + m_pairsOfFlags.push(flag); + return m_pairsOfFlags.length; } function createMemoryArray(uint size) public pure returns (bytes memory) { diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 2ac071375bda..fcf81c2daaaf 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1889,7 +1889,7 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) FunctionCallAnnotation& funcCallAnno = _functionCall.annotation(); FunctionTypePointer functionType = nullptr; - // Determine and assign function call kind, purity and function type for this FunctionCall node + // Determine and assign function call kind, lvalue, purity and function type for this FunctionCall node switch (expressionType->category()) { case Type::Category::Function: @@ -1903,6 +1903,12 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) functionType && functionType->isPure(); + if ( + functionType->kind() == FunctionType::Kind::ArrayPush || + functionType->kind() == FunctionType::Kind::ByteArrayPush + ) + funcCallAnno.isLValue = functionType->parameterTypes().empty(); + break; case Type::Category::TypeType: @@ -2625,7 +2631,10 @@ void TypeChecker::requireLValue(Expression const& _expression) return "Calldata structs are read-only."; } else if (auto arrayType = dynamic_cast(type(memberAccess->expression()))) - if (memberAccess->memberName() == "length") + if ( + memberAccess->memberName() == "length" || + memberAccess->memberName() == "push" + ) switch (arrayType->location()) { case DataLocation::Memory: diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index b509c24957a8..b9f9561cc371 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1781,10 +1781,17 @@ MemberList::MemberMap ArrayType::nativeMembers(ContractDefinition const*) const if (isDynamicallySized() && location() == DataLocation::Storage) { members.emplace_back("push", TypeProvider::function( + TypePointers{}, TypePointers{baseType()}, - TypePointers{TypeProvider::uint256()}, + strings{}, strings{string()}, + isByteArray() ? FunctionType::Kind::ByteArrayPush : FunctionType::Kind::ArrayPush + )); + members.emplace_back("push", TypeProvider::function( + TypePointers{baseType()}, + TypePointers{}, strings{string()}, + strings{}, isByteArray() ? FunctionType::Kind::ByteArrayPush : FunctionType::Kind::ArrayPush )); members.emplace_back("pop", TypeProvider::function( diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 87f1a9d39e08..57a0cb18984d 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -842,41 +842,66 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) case FunctionType::Kind::ArrayPush: { _functionCall.expression().accept(*this); - solAssert(function.parameterTypes().size() == 1, ""); - solAssert(!!function.parameterTypes()[0], ""); - TypePointer paramType = function.parameterTypes()[0]; - ArrayType const* arrayType = - function.kind() == FunctionType::Kind::ArrayPush ? - TypeProvider::array(DataLocation::Storage, paramType) : - TypeProvider::array(DataLocation::Storage); - - // stack: ArrayReference - arguments[0]->accept(*this); - TypePointer const& argType = arguments[0]->annotation().type; - // stack: ArrayReference argValue - utils().moveToStackTop(argType->sizeOnStack(), 1); - // stack: argValue ArrayReference - m_context << Instruction::DUP1; - ArrayUtils(m_context).incrementDynamicArraySize(*arrayType); - // stack: argValue ArrayReference newLength - m_context << Instruction::SWAP1; - // stack: argValue newLength ArrayReference - m_context << u256(1) << Instruction::DUP3 << Instruction::SUB; - // stack: argValue newLength ArrayReference (newLength-1) - ArrayUtils(m_context).accessIndex(*arrayType, false); - // stack: argValue newLength storageSlot slotOffset - utils().moveToStackTop(3, argType->sizeOnStack()); - // stack: newLength storageSlot slotOffset argValue - TypePointer type = arguments[0]->annotation().type->closestTemporaryType(arrayType->baseType()); - solAssert(type, ""); - utils().convertType(*argType, *type); - utils().moveToStackTop(1 + type->sizeOnStack()); - utils().moveToStackTop(1 + type->sizeOnStack()); - // stack: newLength argValue storageSlot slotOffset - if (function.kind() == FunctionType::Kind::ArrayPush) - StorageItem(m_context, *paramType).storeValue(*type, _functionCall.location(), true); + + if (function.parameterTypes().size() == 0) + { + auto paramType = function.returnParameterTypes().at(0); + solAssert(paramType, ""); + + ArrayType const* arrayType = + function.kind() == FunctionType::Kind::ArrayPush ? + TypeProvider::array(DataLocation::Storage, paramType) : + TypeProvider::bytesStorage(); + + // stack: ArrayReference + m_context << u256(1) << Instruction::DUP2; + ArrayUtils(m_context).incrementDynamicArraySize(*arrayType); + // stack: ArrayReference 1 newLength + m_context << Instruction::SUB; + // stack: ArrayReference (newLength-1) + ArrayUtils(m_context).accessIndex(*arrayType, false); + + if (arrayType->isByteArray()) + setLValue(_functionCall); + else + setLValueToStorageItem(_functionCall); + } else - StorageByteArrayElement(m_context).storeValue(*type, _functionCall.location(), true); + { + solAssert(function.parameterTypes().size() == 1, ""); + solAssert(!!function.parameterTypes()[0], ""); + TypePointer paramType = function.parameterTypes()[0]; + ArrayType const* arrayType = + function.kind() == FunctionType::Kind::ArrayPush ? + TypeProvider::array(DataLocation::Storage, paramType) : + TypeProvider::bytesStorage(); + + // stack: ArrayReference + arguments[0]->accept(*this); + TypePointer const& argType = arguments[0]->annotation().type; + // stack: ArrayReference argValue + utils().moveToStackTop(argType->sizeOnStack(), 1); + // stack: argValue ArrayReference + m_context << Instruction::DUP1; + ArrayUtils(m_context).incrementDynamicArraySize(*arrayType); + // stack: argValue ArrayReference newLength + m_context << u256(1) << Instruction::SWAP1 << Instruction::SUB; + // stack: argValue ArrayReference (newLength-1) + ArrayUtils(m_context).accessIndex(*arrayType, false); + // stack: argValue storageSlot slotOffset + utils().moveToStackTop(2, argType->sizeOnStack()); + // stack: storageSlot slotOffset argValue + TypePointer type = arguments[0]->annotation().type->closestTemporaryType(arrayType->baseType()); + solAssert(type, ""); + utils().convertType(*argType, *type); + utils().moveToStackTop(1 + type->sizeOnStack()); + utils().moveToStackTop(1 + type->sizeOnStack()); + // stack: argValue storageSlot slotOffset + if (function.kind() == FunctionType::Kind::ArrayPush) + StorageItem(m_context, *paramType).storeValue(*type, _functionCall.location(), true); + else + StorageByteArrayElement(m_context).storeValue(*type, _functionCall.location(), true); + } break; } case FunctionType::Kind::ArrayPop: diff --git a/test/compilationTests/corion/schelling.sol b/test/compilationTests/corion/schelling.sol index e70716bdf854..9ab24133a2f6 100644 --- a/test/compilationTests/corion/schelling.sol +++ b/test/compilationTests/corion/schelling.sol @@ -70,7 +70,8 @@ contract schellingDB is safeMath, schellingVars { else { return (true, rounds[_id].totalAboveWeight, rounds[_id].totalBelowWeight, rounds[_id].reward, rounds[_id].blockHeight, rounds[_id].voted); } } function pushRound(uint256 _totalAboveWeight, uint256 _totalBelowWeight, uint256 _reward, uint256 _blockHeight, bool _voted) isOwner external returns(bool, uint256) { - return (true, rounds.push(_rounds(_totalAboveWeight, _totalBelowWeight, _reward, _blockHeight, _voted))); + rounds.push(_rounds(_totalAboveWeight, _totalBelowWeight, _reward, _blockHeight, _voted)); + return (true, rounds.length); } function setRound(uint256 _id, uint256 _totalAboveWeight, uint256 _totalBelowWeight, uint256 _reward, uint256 _blockHeight, bool _voted) isOwner external returns(bool) { rounds[_id] = _rounds(_totalAboveWeight, _totalBelowWeight, _reward, _blockHeight, _voted); diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 1e9ce251c6ea..1c14b95a0f35 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -4759,7 +4759,8 @@ BOOST_AUTO_TEST_CASE(array_push) x = data[0]; data.push(4); y = data[1]; - l = data.push(3); + data.push(3); + l = data.length; z = data[2]; } } @@ -4816,11 +4817,13 @@ BOOST_AUTO_TEST_CASE(byte_array_push) contract c { bytes data; function test() public returns (bool x) { - if (data.push(0x05) != 1) return true; + data.push(0x05); + if (data.length != 1) return true; if (data[0] != 0x05) return true; data.push(0x04); if (data[1] != 0x04) return true; - uint l = data.push(0x03); + data.push(0x03); + uint l = data.length; if (data[2] != 0x03) return true; if (l != 0x03) return true; } @@ -4860,7 +4863,8 @@ BOOST_AUTO_TEST_CASE(array_pop) uint[] data; function test() public returns (uint x, uint l) { data.push(7); - x = data.push(3); + data.push(3); + x = data.length; data.pop(); x = data.length; data.pop(); @@ -4996,10 +5000,12 @@ BOOST_AUTO_TEST_CASE(byte_array_pop) bytes data; function test() public returns (uint x, uint y, uint l) { data.push(0x07); - x = data.push(0x03); + data.push(0x03); + x = data.length; data.pop(); data.pop(); - y = data.push(0x02); + data.push(0x02); + y = data.length; l = data.length; } } diff --git a/test/libsolidity/semanticTests/array/push_no_args_1d.sol b/test/libsolidity/semanticTests/array/push_no_args_1d.sol new file mode 100644 index 000000000000..cf6f0687d910 --- /dev/null +++ b/test/libsolidity/semanticTests/array/push_no_args_1d.sol @@ -0,0 +1,32 @@ +contract C { + uint[] array; + + function f() public returns (uint) { + uint y = array.push(); + return y; + } + + function lv(uint value) public { + array.push() = value; + } + + function a(uint index) public view returns (uint) { + return array[index]; + } + + function l() public view returns (uint) { + return array.length; + } + +} +// ---- +// l() -> 0 +// lv(uint256): 42 -> +// l() -> 1 +// a(uint256): 0 -> 42 +// f() -> 0 +// l() -> 2 +// a(uint256): 1 -> 0 +// lv(uint256): 111 -> +// l() -> 3 +// a(uint256): 2 -> 111 diff --git a/test/libsolidity/semanticTests/array/push_no_args_2d.sol b/test/libsolidity/semanticTests/array/push_no_args_2d.sol new file mode 100644 index 000000000000..489510244deb --- /dev/null +++ b/test/libsolidity/semanticTests/array/push_no_args_2d.sol @@ -0,0 +1,39 @@ +contract C { + uint[][] array2d; + + function l() public returns (uint) { + return array2d.length; + } + + function ll(uint index) public returns (uint) { + return array2d[index].length; + } + + function a(uint i, uint j) public returns (uint) { + return array2d[i][j]; + } + + function f(uint index, uint value) public { + uint[] storage pointer = array2d.push(); + for (uint i = 0; i <= index; ++i) + pointer.push(); + pointer[index] = value; + } + + function lv(uint value) public { + array2d.push().push() = value; + } +} +// ---- +// l() -> 0 +// f(uint256,uint256): 42, 64 -> +// l() -> 1 +// ll(uint256): 0 -> 43 +// a(uint256,uint256): 0, 42 -> 64 +// f(uint256,uint256): 84, 128 -> +// l() -> 2 +// ll(uint256): 1 -> 85 +// a(uint256,uint256): 0, 42 -> 64 +// a(uint256,uint256): 1, 84 -> 128 +// lv(uint256): 512 -> +// a(uint256,uint256): 2, 0 -> 512 diff --git a/test/libsolidity/semanticTests/array/push_no_args_bytes.sol b/test/libsolidity/semanticTests/array/push_no_args_bytes.sol new file mode 100644 index 000000000000..dc99dbbd5088 --- /dev/null +++ b/test/libsolidity/semanticTests/array/push_no_args_bytes.sol @@ -0,0 +1,28 @@ +contract C { + bytes array; + + function f() public { + array.push(); + } + + function g(uint x) public { + for (uint i = 0; i < x; ++i) + array.push() = bytes1(uint8(i)); + } + + function l() public returns (uint) { + return array.length; + } + + function a(uint index) public view returns (bytes1) { + return array[index]; + } +} +// ---- +// l() -> 0 +// g(uint256): 70 -> +// l() -> 70 +// a(uint256): 69 -> left(69) +// f() -> +// l() -> 71 +// a(uint256): 70 -> 0 diff --git a/test/libsolidity/semanticTests/array/push_no_args_struct.sol b/test/libsolidity/semanticTests/array/push_no_args_struct.sol new file mode 100644 index 000000000000..6f626d9c350a --- /dev/null +++ b/test/libsolidity/semanticTests/array/push_no_args_struct.sol @@ -0,0 +1,44 @@ +contract C { + struct S { + uint x; + } + + S[] array; + + function f(uint y) public { + S storage s = array.push(); + g(s, y); + } + + function g(S storage s, uint y) internal { + s.x = y; + } + + function h(uint y) public { + g(array.push(), y); + } + + function lv(uint y) public { + array.push().x = y; + } + + function a(uint i) public returns (uint) { + return array[i].x; + } + + function l() public returns (uint) { + return array.length; + } + +} +// ---- +// l() -> 0 +// f(uint256): 42 -> +// l() -> 1 +// a(uint256): 0 -> 42 +// h(uint256): 84 -> +// l() -> 2 +// a(uint256): 1 -> 84 +// lv(uint256): 4096 -> +// l() -> 3 +// a(uint256): 2 -> 4096 From 9ecd51c54ddfce89bcc0daee7a7d7dd3f8e42784 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 5 Sep 2019 23:35:31 +0200 Subject: [PATCH 029/283] Refactor. --- libsolidity/codegen/CompilerUtils.cpp | 20 ++++++++++++++++++++ libsolidity/codegen/CompilerUtils.h | 4 ++++ libsolidity/codegen/ExpressionCompiler.cpp | 19 +------------------ 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index dfeb28db2587..540a4f14ebe4 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -95,6 +95,26 @@ void CompilerUtils::revertWithStringData(Type const& _argumentType) m_context << Instruction::REVERT; } +void CompilerUtils::returnDataToArray() +{ + if (m_context.evmVersion().supportsReturndata()) + { + m_context << Instruction::RETURNDATASIZE; + m_context.appendInlineAssembly(R"({ + switch v case 0 { + v := 0x60 + } default { + v := mload(0x40) + mstore(0x40, add(v, and(add(returndatasize(), 0x3f), not(0x1f)))) + mstore(v, returndatasize()) + returndatacopy(add(v, 0x20), 0, returndatasize()) + } + })", {"v"}); + } + else + pushZeroPointer(); +} + void CompilerUtils::accessCalldataTail(Type const& _type) { solAssert(_type.dataStoredIn(DataLocation::CallData), ""); diff --git a/libsolidity/codegen/CompilerUtils.h b/libsolidity/codegen/CompilerUtils.h index 8c9f1dc4373e..90ea8a15679c 100644 --- a/libsolidity/codegen/CompilerUtils.h +++ b/libsolidity/codegen/CompilerUtils.h @@ -67,6 +67,10 @@ class CompilerUtils /// Stack post: void revertWithStringData(Type const& _argumentType); + /// Allocates a new array and copies the return data to it. + /// If the EVM does not support return data, creates an empty array. + void returnDataToArray(); + /// Computes the absolute calldata offset of a tail given a base reference and the (absolute) /// offset of the tail pointer. Performs bounds checks. If @a _type is a dynamically sized array it also /// returns the array length on the stack. diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 57a0cb18984d..bc4a6de8e903 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -2189,24 +2189,7 @@ void ExpressionCompiler::appendExternalFunctionCall( // an internal helper function e.g. for ``send`` and ``transfer``. In that // case we're only interested in the success condition, not the return data. if (!_functionType.returnParameterTypes().empty()) - { - if (haveReturndatacopy) - { - m_context << Instruction::RETURNDATASIZE; - m_context.appendInlineAssembly(R"({ - switch v case 0 { - v := 0x60 - } default { - v := mload(0x40) - mstore(0x40, add(v, and(add(returndatasize(), 0x3f), not(0x1f)))) - mstore(v, returndatasize()) - returndatacopy(add(v, 0x20), 0, returndatasize()) - } - })", {"v"}); - } - else - utils().pushZeroPointer(); - } + utils().returnDataToArray(); } else if (funKind == FunctionType::Kind::RIPEMD160) { From 36271beca8000b785f4ea015157c22131f25913b Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Thu, 19 Sep 2019 20:08:55 +0200 Subject: [PATCH 030/283] Sets project version to 0.6.0. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a1927bf33a4a..30073fd08ef6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ include(EthPolicy) eth_policy() # project name and version should be set after cmake_policy CMP0048 -set(PROJECT_VERSION "0.5.12") +set(PROJECT_VERSION "0.6.0") project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX) include(TestBigEndian) From a66c3546987886fa215d6b8a0c5e7bad78417e1e Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 2 Sep 2019 16:17:02 +0200 Subject: [PATCH 031/283] AST for try and catch. --- libsolidity/ast/AST.cpp | 7 ++- libsolidity/ast/AST.h | 72 +++++++++++++++++++++++++++- libsolidity/ast/ASTAnnotations.h | 2 + libsolidity/ast/ASTForward.h | 2 + libsolidity/ast/ASTJsonConverter.cpp | 22 ++++++++- libsolidity/ast/ASTJsonConverter.h | 2 + libsolidity/ast/ASTVisitor.h | 8 ++++ libsolidity/ast/AST_accept.h | 42 ++++++++++++++++ 8 files changed, 154 insertions(+), 3 deletions(-) diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 60703f76ef8e..2fec31fdd487 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -448,12 +448,16 @@ bool VariableDeclaration::isLocalVariable() const dynamic_cast(s) || dynamic_cast(s) || dynamic_cast(s) || + dynamic_cast(s) || dynamic_cast(s); } bool VariableDeclaration::isCallableParameter() const { - if (isReturnParameter()) + // TODO Adjust for catch params. + // I think catch params should return true here. + // some of the error strings would need to be adjusted. + if (isReturnParameter() || dynamic_cast(scope())) return true; vector> const* parameters = nullptr; @@ -472,6 +476,7 @@ bool VariableDeclaration::isCallableParameter() const bool VariableDeclaration::isLocalOrReturn() const { + // TODO adjust for catch params return isReturnParameter() || (isLocalVariable() && !isCallableParameter()); } diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 7412626823ad..ce0eb5d62723 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -553,7 +553,7 @@ class EnumValue: public Declaration }; /** - * Parameter list, used as function parameter list and return list. + * Parameter list, used as function parameter list, return list and for try and catch. * None of the parameters is allowed to contain mappings (not even recursively * inside structs). */ @@ -1174,6 +1174,76 @@ class IfStatement: public Statement ASTPointer m_falseBody; ///< "else" part, optional }; +/** + * Clause of a try-catch block. Includes both the successful case and the + * unsuccessful cases. + * Names are only allowed for the unsuccessful cases. + */ +class TryCatchClause: public ASTNode, public Scopable +{ +public: + TryCatchClause( + SourceLocation const& _location, + ASTPointer const& _errorName, + ASTPointer const& _parameters, + ASTPointer const& _block + ): + ASTNode(_location), + m_errorName(_errorName), + m_parameters(_parameters), + m_block(_block) + {} + void accept(ASTVisitor& _visitor) override; + void accept(ASTConstVisitor& _visitor) const override; + + ASTString const& errorName() const { return *m_errorName; } + ParameterList const* parameters() const { return m_parameters.get(); } + Block const& block() const { return *m_block; } + +private: + ASTPointer m_errorName; + ASTPointer m_parameters; + ASTPointer m_block; +}; + +/** + * Try-statement with a variable number of catch statements. + * Syntax: + * try returns (uint x, uint y) { + * // success code + * } catch Error(string memory cause) { + * // error code, reason provided + * } catch (bytes memory lowLevelData) { + * // error code, no reason provided or non-matching error signature. + * } + * + * The last statement given above can also be specified as + * } catch () { + */ +class TryStatement: public Statement +{ +public: + TryStatement( + SourceLocation const& _location, + ASTPointer const& _docString, + ASTPointer const& _externalCall, + std::vector> const& _clauses + ): + Statement(_location, _docString), + m_externalCall(_externalCall), + m_clauses(_clauses) + {} + void accept(ASTVisitor& _visitor) override; + void accept(ASTConstVisitor& _visitor) const override; + + Expression const& externalCall() const { return *m_externalCall; } + std::vector> const& clauses() const { return m_clauses; } + +private: + ASTPointer m_externalCall; + std::vector> m_clauses; +}; + /** * Statement in which a break statement is legal (abstract class). */ diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 539ba85bf592..807d003a22c8 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -218,6 +218,8 @@ enum class FunctionCallKind struct FunctionCallAnnotation: ExpressionAnnotation { FunctionCallKind kind = FunctionCallKind::Unset; + /// If true, this is the external call of a try statement. + bool tryCall = false; }; } diff --git a/libsolidity/ast/ASTForward.h b/libsolidity/ast/ASTForward.h index db6952694842..d950a35f9944 100644 --- a/libsolidity/ast/ASTForward.h +++ b/libsolidity/ast/ASTForward.h @@ -64,6 +64,8 @@ class Statement; class Block; class PlaceholderStatement; class IfStatement; +class TryCatchClause; +class TryStatement; class BreakableStatement; class WhileStatement; class ForStatement; diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index ed5b56d71043..0f2121b7e3d1 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -499,6 +499,25 @@ bool ASTJsonConverter::visit(IfStatement const& _node) return false; } +bool ASTJsonConverter::visit(TryCatchClause const& _node) +{ + setJsonNode(_node, "TryCatchClause", { + make_pair("errorName", _node.errorName()), + make_pair("parameters", toJsonOrNull(_node.parameters())), + make_pair("block", toJson(_node.block())) + }); + return false; +} + +bool ASTJsonConverter::visit(TryStatement const& _node) +{ + setJsonNode(_node, "TryStatement", { + make_pair("externalCall", toJson(_node.externalCall())), + make_pair("clauses", toJson(_node.clauses())) + }); + return false; +} + bool ASTJsonConverter::visit(WhileStatement const& _node) { setJsonNode( @@ -647,7 +666,8 @@ bool ASTJsonConverter::visit(FunctionCall const& _node) std::vector> attributes = { make_pair("expression", toJson(_node.expression())), make_pair("names", std::move(names)), - make_pair("arguments", toJson(_node.arguments())) + make_pair("arguments", toJson(_node.arguments())), + make_pair("tryCall", _node.annotation().tryCall) }; if (m_legacy) { diff --git a/libsolidity/ast/ASTJsonConverter.h b/libsolidity/ast/ASTJsonConverter.h index 0c79d63d13a8..55235f4130db 100644 --- a/libsolidity/ast/ASTJsonConverter.h +++ b/libsolidity/ast/ASTJsonConverter.h @@ -93,6 +93,8 @@ class ASTJsonConverter: public ASTConstVisitor bool visit(Block const& _node) override; bool visit(PlaceholderStatement const& _node) override; bool visit(IfStatement const& _node) override; + bool visit(TryCatchClause const& _node) override; + bool visit(TryStatement const& _node) override; bool visit(WhileStatement const& _node) override; bool visit(ForStatement const& _node) override; bool visit(Continue const& _node) override; diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h index 901b93ef8b27..ed328633fb8b 100644 --- a/libsolidity/ast/ASTVisitor.h +++ b/libsolidity/ast/ASTVisitor.h @@ -69,6 +69,8 @@ class ASTVisitor virtual bool visit(Block& _node) { return visitNode(_node); } virtual bool visit(PlaceholderStatement& _node) { return visitNode(_node); } virtual bool visit(IfStatement& _node) { return visitNode(_node); } + virtual bool visit(TryCatchClause& _node) { return visitNode(_node); } + virtual bool visit(TryStatement& _node) { return visitNode(_node); } virtual bool visit(WhileStatement& _node) { return visitNode(_node); } virtual bool visit(ForStatement& _node) { return visitNode(_node); } virtual bool visit(Continue& _node) { return visitNode(_node); } @@ -117,6 +119,8 @@ class ASTVisitor virtual void endVisit(Block& _node) { endVisitNode(_node); } virtual void endVisit(PlaceholderStatement& _node) { endVisitNode(_node); } virtual void endVisit(IfStatement& _node) { endVisitNode(_node); } + virtual void endVisit(TryCatchClause& _node) { endVisitNode(_node); } + virtual void endVisit(TryStatement& _node) { endVisitNode(_node); } virtual void endVisit(WhileStatement& _node) { endVisitNode(_node); } virtual void endVisit(ForStatement& _node) { endVisitNode(_node); } virtual void endVisit(Continue& _node) { endVisitNode(_node); } @@ -177,6 +181,8 @@ class ASTConstVisitor virtual bool visit(Block const& _node) { return visitNode(_node); } virtual bool visit(PlaceholderStatement const& _node) { return visitNode(_node); } virtual bool visit(IfStatement const& _node) { return visitNode(_node); } + virtual bool visit(TryCatchClause const& _node) { return visitNode(_node); } + virtual bool visit(TryStatement const& _node) { return visitNode(_node); } virtual bool visit(WhileStatement const& _node) { return visitNode(_node); } virtual bool visit(ForStatement const& _node) { return visitNode(_node); } virtual bool visit(Continue const& _node) { return visitNode(_node); } @@ -225,6 +231,8 @@ class ASTConstVisitor virtual void endVisit(Block const& _node) { endVisitNode(_node); } virtual void endVisit(PlaceholderStatement const& _node) { endVisitNode(_node); } virtual void endVisit(IfStatement const& _node) { endVisitNode(_node); } + virtual void endVisit(TryCatchClause const& _node) { endVisitNode(_node); } + virtual void endVisit(TryStatement const& _node) { endVisitNode(_node); } virtual void endVisit(WhileStatement const& _node) { endVisitNode(_node); } virtual void endVisit(ForStatement const& _node) { endVisitNode(_node); } virtual void endVisit(Continue const& _node) { endVisitNode(_node); } diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h index fd676c1ea008..01e0042f8c5d 100644 --- a/libsolidity/ast/AST_accept.h +++ b/libsolidity/ast/AST_accept.h @@ -461,6 +461,48 @@ void IfStatement::accept(ASTConstVisitor& _visitor) const _visitor.endVisit(*this); } +void TryCatchClause::accept(ASTVisitor& _visitor) +{ + if (_visitor.visit(*this)) + { + if (m_parameters) + m_parameters->accept(_visitor); + m_block->accept(_visitor); + } + _visitor.endVisit(*this); +} + +void TryCatchClause::accept(ASTConstVisitor& _visitor) const +{ + if (_visitor.visit(*this)) + { + if (m_parameters) + m_parameters->accept(_visitor); + m_block->accept(_visitor); + } + _visitor.endVisit(*this); +} + +void TryStatement::accept(ASTVisitor& _visitor) +{ + if (_visitor.visit(*this)) + { + m_externalCall->accept(_visitor); + listAccept(m_clauses, _visitor); + } + _visitor.endVisit(*this); +} + +void TryStatement::accept(ASTConstVisitor& _visitor) const +{ + if (_visitor.visit(*this)) + { + m_externalCall->accept(_visitor); + listAccept(m_clauses, _visitor); + } + _visitor.endVisit(*this); +} + void WhileStatement::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) From a54d9d622fdae5ab56989e42ebd935c93cce2179 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 2 Sep 2019 17:25:59 +0200 Subject: [PATCH 032/283] Grammar and Documentation. --- docs/060-breaking-changes.rst | 6 +++ docs/control-structures.rst | 97 ++++++++++++++++++++++++++++++++++- docs/grammar.txt | 4 +- 3 files changed, 105 insertions(+), 2 deletions(-) diff --git a/docs/060-breaking-changes.rst b/docs/060-breaking-changes.rst index effa966f9823..c1c4e8f83e51 100644 --- a/docs/060-breaking-changes.rst +++ b/docs/060-breaking-changes.rst @@ -50,6 +50,12 @@ This section gives detailed instructions on how to update prior code for every b * Change ``uint length = array.push(value)`` to ``array.push(value);``. The new length can be accessed via ``array.length``. +New Features +============ + + * The :ref:`try/catch statement ` allows you to react on failed external calls. + + Deprecated Elements =================== diff --git a/docs/control-structures.rst b/docs/control-structures.rst index 75056dbe6231..4d744e430ff7 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -15,6 +15,10 @@ Most of the control structures known from curly-braces languages are available i There is: ``if``, ``else``, ``while``, ``do``, ``for``, ``break``, ``continue``, ``return``, with the usual semantics known from C or JavaScript. +Solidity also supports exception handling in the form of ``try``/``catch``-statements, +but only for :ref:`external function calls ` and +contract creation calls. + Parentheses can *not* be omitted for conditionals, but curly brances can be omitted around single-statement bodies. @@ -383,7 +387,7 @@ of an exception instead of "bubbling up". .. warning:: The low-level functions ``call``, ``delegatecall`` and ``staticcall`` return ``true`` as their first return value if the account called is non-existent, as part of the design of EVM. Existence must be checked prior to calling if needed. -It is not yet possible to catch exceptions with Solidity. +Exceptions can be caught with the ``try``/``catch`` statement. ``assert`` and ``require`` -------------------------- @@ -488,3 +492,94 @@ In the above example, ``revert("Not enough Ether provided.");`` returns the foll .. note:: There used to be a keyword called ``throw`` with the same semantics as ``revert()`` which was deprecated in version 0.4.13 and removed in version 0.5.0. + + +.. _try-catch: + +``try``/``catch`` +----------------- + +A failure in an external call can be caught using a try/catch statement, as follows: + +:: + + pragma solidity >=0.5.0 <0.7.0; + + interface DataFeed { function getData(address token) external returns (uint value); } + + contract FeedConsumer { + DataFeed feed; + uint errorCount; + function rate(address token) public returns (uint value, bool success) { + // Permanently disable the mechanism if there are + // more than 10 errors. + require(errorCount < 10); + try feed.getData(token) returns (uint v) { + return (v, true); + } catch Error(string memory /*reason*/) { + // This is executed in case + // revert was called inside getData + // and a reason string was provided. + errorCount++; + return (0, false); + } catch (bytes memory /*lowLevelData*/) { + // This is executed in case revert() was used + // or there was a failing assertion, division + // by zero, etc. inside getData. + errorCount++; + return (0, false); + } + } + } + +The ``try`` keyword has to be followed by an expression representing an external function call +or a contract creation (``new ContractName()``). +Errors inside the expression are not caught (for example if it is a complex expression +that also involves internal function calls), only a revert happening inside the external +call itself. The ``returns`` part (which is optional) that follows declares return variables +matching the types returned by the external call. In case there was no error, +these variables are assigned and the contract's execution continues inside the +first success block. If the end of the success block is reached, execution continues after the ``catch`` blocks. + +Currently, Solidity supports different kinds of catch blocks depending on the +type of error. If the error was caused by ``revert("reasonString")`` or +``require(false, "reasonString")`` (or an internal error that causes such an +exception), then the catch clause +of the type ``catch Error(string memory reason)`` will be executed. + +It is planned to support other types of error data in the future. +The string ``Error`` is currently parsed as is and is not treated as an identifier. + +The clause ``catch (bytes memory lowLevelData)`` is executed if the error signature +does not match any other clause, there was an error during decoding of the error +message, if there was a failing assertion in the external +call (for example due to a division by zero or a failing ``assert()``) or +if no error data was provided with the exception. +The declared variable provides access to the low-level error data in that case. + +If you are not interested in the error data, you can just use +``catch { ... }`` (even as the only catch clause). + +In order to catch all error cases, you have to have at least the clause +``catch { ...}`` or the clause ``catch (bytes memory lowLevelData) { ... }``. + +The variables declared in the ``returns`` and the ``catch`` clause are only +in scope in the block that follows. + +.. note:: + + If an error happens during the decoding of the return data + inside a try/catch-statement, this causes an exception in the currently + executing contract and because of that, it is not caught in the catch clause. + If there is an error during decoding of ``catch Error(string memory reason)`` + and there is a low-level catch clause, this error is caught there. + +.. note:: + + If execution reaches a catch-block, then the state-changing effects of + the external call have been reverted. If execution reaches + the success block, the effects were not reverted. + If the effects have been reverted, then execution either continues + in a catch block or the execution of the try/catch statement itself + reverts (for example due to decoding failures as noted above or + due to not providing a low-level catch clause). \ No newline at end of file diff --git a/docs/grammar.txt b/docs/grammar.txt index 4433b4a4308a..a04ec070578d 100644 --- a/docs/grammar.txt +++ b/docs/grammar.txt @@ -62,12 +62,14 @@ StorageLocation = 'memory' | 'storage' | 'calldata' StateMutability = 'pure' | 'view' | 'payable' Block = '{' Statement* '}' -Statement = IfStatement | WhileStatement | ForStatement | Block | InlineAssemblyStatement | +Statement = IfStatement | TryStatement | WhileStatement | ForStatement | Block | InlineAssemblyStatement | ( DoWhileStatement | PlaceholderStatement | Continue | Break | Return | Throw | EmitStatement | SimpleStatement ) ';' ExpressionStatement = Expression IfStatement = 'if' '(' Expression ')' Statement ( 'else' Statement )? +TryStatement = 'try' Expression ( 'returns' ParameterList )? Block CatchClause+ +CatchClause = 'catch' Identifier? ParameterList Block WhileStatement = 'while' '(' Expression ')' Statement PlaceholderStatement = '_' SimpleStatement = VariableDefinition | ExpressionStatement From 6d6914f98f96ba6c5f8285bb0e8c7ef63269920a Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 3 Sep 2019 16:06:00 +0200 Subject: [PATCH 033/283] Parser for try/catch. --- libsolidity/parsing/Parser.cpp | 70 +++++++++++++++++++++++++++++++--- libsolidity/parsing/Parser.h | 2 + 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 9601389c7750..dece4fa142b0 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1099,13 +1099,15 @@ ASTPointer Parser::parseStatement() } statement = nodeFactory.createNode(docString, expression); break; - } + } case Token::Throw: - { - statement = ASTNodeFactory(*this).createNode(docString); - m_scanner->next(); - break; - } + { + statement = ASTNodeFactory(*this).createNode(docString); + m_scanner->next(); + break; + } + case Token::Try: + return parseTryStatement(docString); case Token::Assembly: return parseInlineAssembly(docString); case Token::Emit: @@ -1187,6 +1189,62 @@ ASTPointer Parser::parseIfStatement(ASTPointer const& _d return nodeFactory.createNode(_docString, condition, trueBody, falseBody); } +ASTPointer Parser::parseTryStatement(ASTPointer const& _docString) +{ + RecursionGuard recursionGuard(*this); + ASTNodeFactory nodeFactory(*this); + expectToken(Token::Try); + ASTPointer externalCall = parseExpression(); + vector> clauses; + + ASTNodeFactory successClauseFactory(*this); + ASTPointer returnsParameters; + if (m_scanner->currentToken() == Token::Returns) + { + m_scanner->next(); + VarDeclParserOptions options; + options.allowEmptyName = true; + options.allowLocationSpecifier = true; + returnsParameters = parseParameterList(options, false); + } + ASTPointer successBlock = parseBlock(); + successClauseFactory.setEndPositionFromNode(successBlock); + clauses.emplace_back(successClauseFactory.createNode( + make_shared(), returnsParameters, successBlock + )); + + do + { + clauses.emplace_back(parseCatchClause()); + } + while (m_scanner->currentToken() == Token::Catch); + nodeFactory.setEndPositionFromNode(clauses.back()); + return nodeFactory.createNode( + _docString, externalCall, clauses + ); +} + +ASTPointer Parser::parseCatchClause() +{ + RecursionGuard recursionGuard(*this); + ASTNodeFactory nodeFactory(*this); + expectToken(Token::Catch); + ASTPointer errorName = make_shared(); + ASTPointer errorParameters; + if (m_scanner->currentToken() != Token::LBrace) + { + if (m_scanner->currentToken() == Token::Identifier) + errorName = expectIdentifierToken(); + VarDeclParserOptions options; + options.allowEmptyName = true; + options.allowLocationSpecifier = true; + errorParameters = parseParameterList(options, !errorName->empty()); + } + ASTPointer block = parseBlock(); + nodeFactory.setEndPositionFromNode(block); + return nodeFactory.createNode(errorName, errorParameters, block); +} + ASTPointer Parser::parseWhileStatement(ASTPointer const& _docString) { RecursionGuard recursionGuard(*this); diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index 479306fb00eb..bd288d34c8b5 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -119,6 +119,8 @@ class Parser: public langutil::ParserBase ASTPointer parseStatement(); ASTPointer parseInlineAssembly(ASTPointer const& _docString = {}); ASTPointer parseIfStatement(ASTPointer const& _docString); + ASTPointer parseTryStatement(ASTPointer const& _docString); + ASTPointer parseCatchClause(); ASTPointer parseWhileStatement(ASTPointer const& _docString); ASTPointer parseDoWhileStatement(ASTPointer const& _docString); ASTPointer parseForStatement(ASTPointer const& _docString); From 644a402166e3feaebb684795801706c3b0b1238f Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 3 Sep 2019 18:31:17 +0200 Subject: [PATCH 034/283] Tests. --- test/libsolidity/ASTJSON/address_payable.json | 2 + .../ASTJSON/address_payable_legacy.json | 2 + test/libsolidity/SolidityEndToEndTest.cpp | 53 ++++++ .../tryCatch/invalid_error_encoding.sol | 168 ++++++++++++++++++ .../semanticTests/tryCatch/lowLevel.sol | 18 ++ .../semanticTests/tryCatch/nested.sol | 33 ++++ .../tryCatch/return_function.sol | 17 ++ .../semanticTests/tryCatch/simple.sol | 18 ++ .../semanticTests/tryCatch/structured.sol | 19 ++ .../tryCatch/structuredAndLowLevel.sol | 23 +++ .../semanticTests/tryCatch/trivial.sol | 16 ++ .../syntaxTests/tryCatch/catch_error.sol | 11 ++ .../tryCatch/catch_error_named.sol | 11 ++ .../syntaxTests/tryCatch/catch_low_level.sol | 11 ++ .../syntaxTests/tryCatch/empty_catch.sol | 11 ++ .../syntaxTests/tryCatch/empty_returns.sol | 11 ++ .../tryCatch/error_with_wrong_type.sol | 12 ++ .../tryCatch/invalid_error_name.sol | 11 ++ .../syntaxTests/tryCatch/invalid_returns.sol | 13 ++ .../syntaxTests/tryCatch/library_call.sol | 40 +++++ .../tryCatch/low_level_pre-byzantium.sol | 13 ++ .../tryCatch/low_level_with_wrong_type.sol | 12 ++ .../syntaxTests/tryCatch/no_catch.sol | 8 + .../syntaxTests/tryCatch/no_external_call.sol | 9 + .../syntaxTests/tryCatch/no_returns.sol | 9 + .../syntaxTests/tryCatch/returns.sol | 10 ++ .../syntaxTests/tryCatch/returns_memory.sol | 11 ++ .../tryCatch/returns_memory_anonymous.sol | 11 ++ .../syntaxTests/tryCatch/simple_catch.sol | 9 + .../tryCatch/structured_pre_byzantium.sol | 13 ++ .../tryCatch/two_catch_clauses.sol | 14 ++ .../tryCatch/two_error_catch_clauses.sol | 15 ++ .../tryCatch/two_low_level_catch_clauses.sol | 14 ++ .../syntaxTests/unusedVariables/try_catch.sol | 18 ++ 34 files changed, 666 insertions(+) create mode 100644 test/libsolidity/semanticTests/tryCatch/invalid_error_encoding.sol create mode 100644 test/libsolidity/semanticTests/tryCatch/lowLevel.sol create mode 100644 test/libsolidity/semanticTests/tryCatch/nested.sol create mode 100644 test/libsolidity/semanticTests/tryCatch/return_function.sol create mode 100644 test/libsolidity/semanticTests/tryCatch/simple.sol create mode 100644 test/libsolidity/semanticTests/tryCatch/structured.sol create mode 100644 test/libsolidity/semanticTests/tryCatch/structuredAndLowLevel.sol create mode 100644 test/libsolidity/semanticTests/tryCatch/trivial.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/catch_error.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/catch_error_named.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/catch_low_level.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/empty_catch.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/empty_returns.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/error_with_wrong_type.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/invalid_error_name.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/invalid_returns.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/library_call.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/low_level_pre-byzantium.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/low_level_with_wrong_type.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/no_catch.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/no_external_call.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/no_returns.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/returns.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/returns_memory.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/returns_memory_anonymous.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/simple_catch.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/structured_pre_byzantium.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/two_catch_clauses.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/two_error_catch_clauses.sol create mode 100644 test/libsolidity/syntaxTests/tryCatch/two_low_level_catch_clauses.sol create mode 100644 test/libsolidity/syntaxTests/unusedVariables/try_catch.sol diff --git a/test/libsolidity/ASTJSON/address_payable.json b/test/libsolidity/ASTJSON/address_payable.json index 834fb1cc92b9..738d8371dbbd 100644 --- a/test/libsolidity/ASTJSON/address_payable.json +++ b/test/libsolidity/ASTJSON/address_payable.json @@ -321,6 +321,7 @@ "names" : [], "nodeType" : "FunctionCall", "src" : "209:13:1", + "tryCall" : false, "typeDescriptions" : { "typeIdentifier" : "t_address", @@ -444,6 +445,7 @@ "names" : [], "nodeType" : "FunctionCall", "src" : "239:10:1", + "tryCall" : false, "typeDescriptions" : { "typeIdentifier" : "t_address_payable", diff --git a/test/libsolidity/ASTJSON/address_payable_legacy.json b/test/libsolidity/ASTJSON/address_payable_legacy.json index 0b10724607b9..afcf195a5812 100644 --- a/test/libsolidity/ASTJSON/address_payable_legacy.json +++ b/test/libsolidity/ASTJSON/address_payable_legacy.json @@ -396,6 +396,7 @@ [ null ], + "tryCall" : false, "type" : "address", "type_conversion" : true }, @@ -526,6 +527,7 @@ [ null ], + "tryCall" : false, "type" : "address payable", "type_conversion" : true }, diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 1c14b95a0f35..f9e5f6fc3bc2 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -14784,6 +14784,59 @@ BOOST_AUTO_TEST_CASE(dirty_scratch_space_prior_to_constant_optimiser) ); } +BOOST_AUTO_TEST_CASE(try_catch_library_call) +{ + char const* sourceCode = R"( + library L { + struct S { uint x; } + function integer(uint t, bool b) public view returns (uint) { + if (b) { + return t; + } else { + revert("failure"); + } + } + function stru(S storage t, bool b) public view returns (uint) { + if (b) { + return t.x; + } else { + revert("failure"); + } + } + } + contract C { + using L for L.S; + L.S t; + function f(bool b) public returns (uint, string memory) { + uint x = 8; + try L.integer(x, b) returns (uint _x) { + return (_x, ""); + } catch Error(string memory message) { + return (18, message); + } + } + function g(bool b) public returns (uint, string memory) { + t.x = 9; + try t.stru(b) returns (uint x) { + return (x, ""); + } catch Error(string memory message) { + return (19, message); + } + } + } + )"; + if (dev::test::Options::get().evmVersion().supportsReturndata()) + { + compileAndRun(sourceCode, 0, "L", bytes()); + compileAndRun(sourceCode, 0, "C", bytes(), map{{"L", m_contractAddress}}); + + ABI_CHECK(callContractFunction("f(bool)", true), encodeArgs(8, 0x40, 0)); + ABI_CHECK(callContractFunction("f(bool)", false), encodeArgs(18, 0x40, 7, "failure")); + ABI_CHECK(callContractFunction("g(bool)", true), encodeArgs(9, 0x40, 0)); + ABI_CHECK(callContractFunction("g(bool)", false), encodeArgs(19, 0x40, 7, "failure")); + } +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/semanticTests/tryCatch/invalid_error_encoding.sol b/test/libsolidity/semanticTests/tryCatch/invalid_error_encoding.sol new file mode 100644 index 000000000000..2bfc23191f77 --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/invalid_error_encoding.sol @@ -0,0 +1,168 @@ +contract C { + function g(bytes memory revertMsg) public pure returns (uint, uint) { + assembly { revert(add(revertMsg, 0x20), mload(revertMsg)) } + } + function f1() public returns (uint x) { + // Invalid signature + try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch (bytes memory) { + return 2; + } + } + function f1a() public returns (uint x) { + // Invalid signature + try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch { + return 2; + } + } + function f1b() public returns (uint x) { + // Invalid signature + try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } + } + function f1c() public returns (uint x) { + // Invalid signature + try this.g(abi.encodeWithSelector(0x12345678, uint(0), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch { + return 2; + } + } + function f2() public returns (uint x) { + // Valid signature but illegal offset + try this.g(abi.encodeWithSignature("Error(string)", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch (bytes memory) { + return 2; + } + } + function f2a() public returns (uint x) { + // Valid signature but illegal offset + try this.g(abi.encodeWithSignature("Error(string)", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch { + return 2; + } + } + function f2b() public returns (uint x) { + // Valid signature but illegal offset + try this.g(abi.encodeWithSignature("Error(string)", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } + } + function f2c() public returns (uint x) { + // Valid signature but illegal offset + try this.g(abi.encodeWithSignature("Error(string)", uint(0x100), uint(0), uint(0))) returns (uint a, uint b) { + return 0; + } catch { + return 1; + } + } + function f3() public returns (uint x) { + // Valid up to length + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch (bytes memory) { + return 2; + } + } + function f3a() public returns (uint x) { + // Valid up to length + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch (bytes memory) { + return 2; + } + } + function f3b() public returns (uint x) { + // Valid up to length + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } + } + function f3c() public returns (uint x) { + // Valid up to length + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x30), uint(0))) returns (uint a, uint b) { + return 0; + } catch { + return 1; + } + } + function f4() public returns (uint x) { + // Fully valid + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x7), bytes7("abcdefg"))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch (bytes memory) { + return 2; + } + } + function f4a() public returns (uint x) { + // Fully valid + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x7), bytes7("abcdefg"))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } catch { + return 2; + } + } + function f4b() public returns (uint x) { + // Fully valid + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x7), bytes7("abcdefg"))) returns (uint a, uint b) { + return 0; + } catch Error(string memory) { + return 1; + } + } + function f4c() public returns (uint x) { + // Fully valid + try this.g(abi.encodeWithSignature("Error(string)", uint(0x20), uint(0x7), bytes7("abcdefg"))) returns (uint a, uint b) { + return 0; + } catch { + return 1; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f1() -> 2 +// f1a() -> 2 +// f1b() -> FAILURE, hex"12345678", 0x0, 0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +// f1c() -> 2 +// f2() -> 2 +// f2a() -> 2 +// f2b() -> FAILURE, hex"08c379a0", 0x100, 0, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +// f2c() -> 1 +// f3() -> 2 +// f3a() -> 2 +// f3b() -> FAILURE, hex"08c379a0", 0x20, 48, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" +// f3c() -> 1 +// f4() -> 1 +// f4a() -> 1 +// f4b() -> 1 +// f4c() -> 1 diff --git a/test/libsolidity/semanticTests/tryCatch/lowLevel.sol b/test/libsolidity/semanticTests/tryCatch/lowLevel.sol new file mode 100644 index 000000000000..ac275522d9e5 --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/lowLevel.sol @@ -0,0 +1,18 @@ +contract C { + function g(bool b) public pure returns (uint, uint) { + require(b, "message"); + return (1, 2); + } + function f(bool b) public returns (uint x, uint y, bytes memory txt) { + try this.g(b) returns (uint a, uint b) { + (x, y) = (a, b); + } catch (bytes memory s) { + txt = s; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(bool): true -> 1, 2, 96, 0 +// f(bool): false -> 0, 0, 96, 100, 0x8c379a000000000000000000000000000000000000000000000000000000000, 0x2000000000000000000000000000000000000000000000000000000000, 0x76d657373616765000000000000000000000000000000000000000000, 0 diff --git a/test/libsolidity/semanticTests/tryCatch/nested.sol b/test/libsolidity/semanticTests/tryCatch/nested.sol new file mode 100644 index 000000000000..7c56a81b78d1 --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/nested.sol @@ -0,0 +1,33 @@ +contract C { + function g(bool b) public pure returns (uint, uint) { + require(b, "failure"); + return (1, 2); + } + function f(bool cond1, bool cond2) public returns (uint x, uint y, bytes memory txt) { + try this.g(cond1) returns (uint a, uint b) { + try this.g(cond2) returns (uint a2, uint b2) { + (x, y) = (a, b); + txt = "success"; + } catch Error(string memory s) { + x = 12; + txt = bytes(s); + } catch (bytes memory s) { + x = 13; + txt = s; + } + } catch Error(string memory s) { + x = 99; + txt = bytes(s); + } catch (bytes memory s) { + x = 98; + txt = s; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(bool,bool): true, true -> 1, 2, 96, 7, "success" +// f(bool,bool): true, false -> 12, 0, 96, 7, "failure" +// f(bool,bool): false, true -> 99, 0, 96, 7, "failure" +// f(bool,bool): false, false -> 99, 0, 96, 7, "failure" diff --git a/test/libsolidity/semanticTests/tryCatch/return_function.sol b/test/libsolidity/semanticTests/tryCatch/return_function.sol new file mode 100644 index 000000000000..82d5dc821218 --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/return_function.sol @@ -0,0 +1,17 @@ +contract C { + function g() public returns (uint a, function() external h, uint b) { + a = 1; + h = this.fun; + b = 9; + } + function f() public returns (uint, function() external, uint) { + // Note that the function type uses two stack slots. + try this.g() returns (uint a, function() external h, uint b) { + return (a, h, b); + } catch { + } + } + function fun() public pure {} +} +// ---- +// f() -> 0x1, 0xfdd67305928fcac8d213d1e47bfa6165cd0b87b946644cd0000000000000000, 9 diff --git a/test/libsolidity/semanticTests/tryCatch/simple.sol b/test/libsolidity/semanticTests/tryCatch/simple.sol new file mode 100644 index 000000000000..b7f36701695e --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/simple.sol @@ -0,0 +1,18 @@ +contract C { + function g(bool b) public pure returns (uint, uint) { + require(b); + return (1, 2); + } + function f(bool b) public returns (uint x, uint y) { + try this.g(b) returns (uint a, uint b) { + (x, y) = (a, b); + } catch { + (x, y) = (9, 10); + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(bool): true -> 1, 2 +// f(bool): false -> 9, 10 diff --git a/test/libsolidity/semanticTests/tryCatch/structured.sol b/test/libsolidity/semanticTests/tryCatch/structured.sol new file mode 100644 index 000000000000..e5aa238b30da --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/structured.sol @@ -0,0 +1,19 @@ +contract C { + function g(bool b) public pure returns (uint, uint) { + require(b, "message"); + return (1, 2); + } + function f(bool b) public returns (uint x, uint y, string memory txt) { + try this.g(b) returns (uint a, uint b) { + (x, y) = (a, b); + txt = "success"; + } catch Error(string memory s) { + txt = s; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(bool): true -> 1, 2, 0x60, 7, "success" +// f(bool): false -> 0, 0, 0x60, 7, "message" diff --git a/test/libsolidity/semanticTests/tryCatch/structuredAndLowLevel.sol b/test/libsolidity/semanticTests/tryCatch/structuredAndLowLevel.sol new file mode 100644 index 000000000000..8a8cb3d1b62f --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/structuredAndLowLevel.sol @@ -0,0 +1,23 @@ +contract C { + function g(bool b) public pure returns (uint, uint) { + require(b, "message longer than 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes 32 bytes"); + return (1, 2); + } + function f(bool cond) public returns (uint x, uint y, bytes memory txt) { + try this.g(cond) returns (uint a, uint b) { + (x, y) = (a, b); + txt = "success"; + } catch Error(string memory s) { + x = 99; + txt = bytes(s); + } catch (bytes memory s) { + x = 98; + txt = s; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f(bool): true -> 1, 2, 96, 7, "success" +// f(bool): false -> 99, 0, 96, 82, "message longer than 32 bytes 32 ", "bytes 32 bytes 32 bytes 32 bytes", " 32 bytes 32 bytes" diff --git a/test/libsolidity/semanticTests/tryCatch/trivial.sol b/test/libsolidity/semanticTests/tryCatch/trivial.sol new file mode 100644 index 000000000000..e2f8739bd7d0 --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/trivial.sol @@ -0,0 +1,16 @@ +contract C { + function g(bool x) public pure { + require(x); + } + function f(bool x) public returns (uint) { + // Set the gas to make this work on pre-byzantium VMs + try this.g.gas(8000)(x) { + return 1; + } catch { + return 2; + } + } +} +// ---- +// f(bool): true -> 1 +// f(bool): false -> 2 diff --git a/test/libsolidity/syntaxTests/tryCatch/catch_error.sol b/test/libsolidity/syntaxTests/tryCatch/catch_error.sol new file mode 100644 index 000000000000..34fc2431eb55 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/catch_error.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (uint, uint) { + try this.f() { + + } catch Error(string memory) { + + } + } +} +// ==== +// EVMVersion: >=byzantium \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/tryCatch/catch_error_named.sol b/test/libsolidity/syntaxTests/tryCatch/catch_error_named.sol new file mode 100644 index 000000000000..1a4a1273a7ce --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/catch_error_named.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (uint, uint) { + try this.f() { + + } catch Error(string memory x) { + x; + } + } +} +// ==== +// EVMVersion: >=byzantium \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/tryCatch/catch_low_level.sol b/test/libsolidity/syntaxTests/tryCatch/catch_low_level.sol new file mode 100644 index 000000000000..58948e211267 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/catch_low_level.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (uint, uint) { + try this.f() { + + } catch (bytes memory x) { + x; + } + } +} +// ==== +// EVMVersion: >=byzantium \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/tryCatch/empty_catch.sol b/test/libsolidity/syntaxTests/tryCatch/empty_catch.sol new file mode 100644 index 000000000000..ee887fe1ad8c --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/empty_catch.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (uint, uint) { + try this.f() { + + } catch () { + + } + } +} +// ---- +// ParserError: (101-102): Expected type name diff --git a/test/libsolidity/syntaxTests/tryCatch/empty_returns.sol b/test/libsolidity/syntaxTests/tryCatch/empty_returns.sol new file mode 100644 index 000000000000..ba1ba2202149 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/empty_returns.sol @@ -0,0 +1,11 @@ +contract C { + function f() public { + try this.f() returns () { + + } catch { + + } + } +} +// ---- +// ParserError: (69-70): Expected type name diff --git a/test/libsolidity/syntaxTests/tryCatch/error_with_wrong_type.sol b/test/libsolidity/syntaxTests/tryCatch/error_with_wrong_type.sol new file mode 100644 index 000000000000..05878ba5baf7 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/error_with_wrong_type.sol @@ -0,0 +1,12 @@ +contract C { + function f() public returns (uint, uint) { + try this.f() { + + } catch Error(uint) { + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// TypeError: (94-123): Expected `catch Error(string memory ...) { ... }`. diff --git a/test/libsolidity/syntaxTests/tryCatch/invalid_error_name.sol b/test/libsolidity/syntaxTests/tryCatch/invalid_error_name.sol new file mode 100644 index 000000000000..164da567daa7 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/invalid_error_name.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (uint, uint) { + try this.f() { + } catch Error2() { + } catch abc() { + } + } +} +// ---- +// TypeError: (93-119): Invalid catch clause name. Expected either `catch (...)` or `catch Error(...)`. +// TypeError: (120-143): Invalid catch clause name. Expected either `catch (...)` or `catch Error(...)`. diff --git a/test/libsolidity/syntaxTests/tryCatch/invalid_returns.sol b/test/libsolidity/syntaxTests/tryCatch/invalid_returns.sol new file mode 100644 index 000000000000..e1d22f05f611 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/invalid_returns.sol @@ -0,0 +1,13 @@ +contract C { + function f() public returns (uint8, uint) { + // Implicitly convertible, but not exactly the same type. + try this.f() returns (uint, int x) { + + } catch { + + } + } +} +// ---- +// TypeError: (157-161): Invalid type, expected uint8 but got uint256. +// TypeError: (163-168): Invalid type, expected uint256 but got int256. diff --git a/test/libsolidity/syntaxTests/tryCatch/library_call.sol b/test/libsolidity/syntaxTests/tryCatch/library_call.sol new file mode 100644 index 000000000000..b2ceaa6a5b2b --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/library_call.sol @@ -0,0 +1,40 @@ +library L { + struct S { uint x; } + function integer(uint t, bool b) public pure returns (uint) { + if (b) { + return t; + } else { + revert("failure"); + } + } + function stru(S storage t, bool b) public view returns (uint) { + if (b) { + return t.x; + } else { + revert("failure"); + } + } +} +contract C { + using L for L.S; + L.S t; + function f(bool b) public pure returns (uint, string memory) { + uint x = 8; + try L.integer(x, b) returns (uint _x) { + return (_x, ""); + } catch Error(string memory message) { + return (18, message); + } + } + function g(bool b) public returns (uint, string memory) { + t.x = 9; + try t.stru(b) returns (uint x) { + return (x, ""); + } catch Error(string memory message) { + return (19, message); + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- diff --git a/test/libsolidity/syntaxTests/tryCatch/low_level_pre-byzantium.sol b/test/libsolidity/syntaxTests/tryCatch/low_level_pre-byzantium.sol new file mode 100644 index 000000000000..3dd16df11765 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/low_level_pre-byzantium.sol @@ -0,0 +1,13 @@ +contract C { + function f() public { + try this.f() { + + } catch (bytes memory) { + + } + } +} +// ==== +// EVMVersion: =byzantium +// ---- +// TypeError: (94-118): Expected `catch (bytes memory ...) { ... }` or `catch { ... }`. diff --git a/test/libsolidity/syntaxTests/tryCatch/no_catch.sol b/test/libsolidity/syntaxTests/tryCatch/no_catch.sol new file mode 100644 index 000000000000..28938d3ddb13 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/no_catch.sol @@ -0,0 +1,8 @@ +contract C { + function f() public returns (uint, uint) { + try this.f() { + } + } +} +// ---- +// ParserError: (97-98): Expected reserved keyword 'catch' but got '}' diff --git a/test/libsolidity/syntaxTests/tryCatch/no_external_call.sol b/test/libsolidity/syntaxTests/tryCatch/no_external_call.sol new file mode 100644 index 000000000000..1ae24a80234c --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/no_external_call.sol @@ -0,0 +1,9 @@ +contract C { + function f() public returns (uint, uint) { + try f() { + } catch { + } + } +} +// ---- +// TypeError: (72-75): Try can only be used with external function calls and contract creation calls. diff --git a/test/libsolidity/syntaxTests/tryCatch/no_returns.sol b/test/libsolidity/syntaxTests/tryCatch/no_returns.sol new file mode 100644 index 000000000000..bfda49ab9573 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/no_returns.sol @@ -0,0 +1,9 @@ +contract C { + function f() public returns (uint, uint) { + try this.f() { + + } catch { + + } + } +} \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/tryCatch/returns.sol b/test/libsolidity/syntaxTests/tryCatch/returns.sol new file mode 100644 index 000000000000..507a83905eba --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/returns.sol @@ -0,0 +1,10 @@ +contract C { + function f() public returns (uint, uint) { + try this.f() returns (uint a, uint b) { + a = 1; + b = 2; + } catch { + + } + } +} diff --git a/test/libsolidity/syntaxTests/tryCatch/returns_memory.sol b/test/libsolidity/syntaxTests/tryCatch/returns_memory.sol new file mode 100644 index 000000000000..f71a4af25c98 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/returns_memory.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (uint[] memory, uint) { + try this.f() returns (uint[] memory x, uint y) { + return (x, y); + } catch { + + } + } +} +// ==== +// EVMVersion: >=byzantium diff --git a/test/libsolidity/syntaxTests/tryCatch/returns_memory_anonymous.sol b/test/libsolidity/syntaxTests/tryCatch/returns_memory_anonymous.sol new file mode 100644 index 000000000000..9eb8f86c4787 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/returns_memory_anonymous.sol @@ -0,0 +1,11 @@ +contract C { + function f() public returns (uint[] memory, uint) { + try this.f() returns (uint[] memory, uint) { + + } catch { + + } + } +} +// ==== +// EVMVersion: >=byzantium \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/tryCatch/simple_catch.sol b/test/libsolidity/syntaxTests/tryCatch/simple_catch.sol new file mode 100644 index 000000000000..df33d2a50991 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/simple_catch.sol @@ -0,0 +1,9 @@ +contract C { + function f() public { + try this.f() { + + } catch { + + } + } +} \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/tryCatch/structured_pre_byzantium.sol b/test/libsolidity/syntaxTests/tryCatch/structured_pre_byzantium.sol new file mode 100644 index 000000000000..34c7e501123a --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/structured_pre_byzantium.sol @@ -0,0 +1,13 @@ +contract C { + function f() public { + try this.f() { + + } catch Error(string memory) { + + } + } +} +// ==== +// EVMVersion: =byzantium \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/tryCatch/two_error_catch_clauses.sol b/test/libsolidity/syntaxTests/tryCatch/two_error_catch_clauses.sol new file mode 100644 index 000000000000..72f77c4a66a4 --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/two_error_catch_clauses.sol @@ -0,0 +1,15 @@ +contract C { + function f() public returns (uint, uint) { + try this.f() { + + } catch Error(string memory x) { + x; + } catch Error(string memory y) { + y; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// TypeError: (150-205): This try statement already has an "Error" catch clause. diff --git a/test/libsolidity/syntaxTests/tryCatch/two_low_level_catch_clauses.sol b/test/libsolidity/syntaxTests/tryCatch/two_low_level_catch_clauses.sol new file mode 100644 index 000000000000..108160aae7df --- /dev/null +++ b/test/libsolidity/syntaxTests/tryCatch/two_low_level_catch_clauses.sol @@ -0,0 +1,14 @@ +contract C { + function f() public returns (uint, uint) { + try this.f() { + + } catch { + } catch (bytes memory y) { + y; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// TypeError: (112-161): This try statement already has a low-level catch clause. diff --git a/test/libsolidity/syntaxTests/unusedVariables/try_catch.sol b/test/libsolidity/syntaxTests/unusedVariables/try_catch.sol new file mode 100644 index 000000000000..d829cfc7d6c6 --- /dev/null +++ b/test/libsolidity/syntaxTests/unusedVariables/try_catch.sol @@ -0,0 +1,18 @@ +contract test { + function f() public returns (uint b) { + try this.f() returns (uint a) { + + } catch Error(string memory message) { + + } catch (bytes memory error) { + + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// Warning: (49-55): Unused function parameter. Remove or comment out the variable name to silence this warning. +// Warning: (89-95): Unused try/catch parameter. Remove or comment out the variable name to silence this warning. +// Warning: (122-143): Unused try/catch parameter. Remove or comment out the variable name to silence this warning. +// Warning: (165-183): Unused try/catch parameter. Remove or comment out the variable name to silence this warning. From b5bc52f2a7861b550b8474e1ffd000e3f1234648 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 5 Sep 2019 20:02:09 +0200 Subject: [PATCH 035/283] Control flow for try statements. --- libsolidity/analysis/ControlFlowBuilder.cpp | 12 +++++++ libsolidity/analysis/ControlFlowBuilder.h | 20 +++++++++-- .../controlFlow/storageReturn/try_err.sol | 34 +++++++++++++++++++ .../controlFlow/storageReturn/try_fine.sol | 24 +++++++++++++ 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/syntaxTests/controlFlow/storageReturn/try_err.sol create mode 100644 test/libsolidity/syntaxTests/controlFlow/storageReturn/try_fine.sol diff --git a/libsolidity/analysis/ControlFlowBuilder.cpp b/libsolidity/analysis/ControlFlowBuilder.cpp index fb766eea9f9e..6774b6e38f4b 100644 --- a/libsolidity/analysis/ControlFlowBuilder.cpp +++ b/libsolidity/analysis/ControlFlowBuilder.cpp @@ -85,6 +85,18 @@ bool ControlFlowBuilder::visit(Conditional const& _conditional) return false; } +bool ControlFlowBuilder::visit(TryStatement const& _tryStatement) +{ + appendControlFlow(_tryStatement.externalCall()); + + auto nodes = splitFlow(_tryStatement.clauses().size()); + for (size_t i = 0; i < _tryStatement.clauses().size(); ++i) + nodes[i] = createFlow(nodes[i], _tryStatement.clauses()[i]->block()); + mergeFlow(nodes); + + return false; +} + bool ControlFlowBuilder::visit(IfStatement const& _ifStatement) { solAssert(!!m_currentNode, ""); diff --git a/libsolidity/analysis/ControlFlowBuilder.h b/libsolidity/analysis/ControlFlowBuilder.h index b17483954b48..91b112eb5873 100644 --- a/libsolidity/analysis/ControlFlowBuilder.h +++ b/libsolidity/analysis/ControlFlowBuilder.h @@ -45,6 +45,7 @@ class ControlFlowBuilder: private ASTConstVisitor // Visits for constructing the control flow. bool visit(BinaryOperation const& _operation) override; bool visit(Conditional const& _conditional) override; + bool visit(TryStatement const& _tryStatement) override; bool visit(IfStatement const& _ifStatement) override; bool visit(ForStatement const& _forStatement) override; bool visit(WhileStatement const& _whileStatement) override; @@ -98,12 +99,27 @@ class ControlFlowBuilder: private ASTConstVisitor return result; } + /// Splits the control flow starting at the current node into @a _n paths. + /// m_currentNode is set to nullptr and has to be set manually or + /// using mergeFlow later. + std::vector splitFlow(size_t n) + { + std::vector result(n); + for (auto& node: result) + { + node = m_nodeContainer.newNode(); + connect(m_currentNode, node); + } + m_currentNode = nullptr; + return result; + } + /// Merges the control flow of @a _nodes to @a _endNode. /// If @a _endNode is nullptr, a new node is creates and used as end node. /// Sets the merge destination as current node. /// Note: @a _endNode may be one of the nodes in @a _nodes. - template - void mergeFlow(std::array const& _nodes, CFGNode* _endNode = nullptr) + template + void mergeFlow(C const& _nodes, CFGNode* _endNode = nullptr) { CFGNode* mergeDestination = (_endNode == nullptr) ? m_nodeContainer.newNode() : _endNode; for (auto& node: _nodes) diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/try_err.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/try_err.sol new file mode 100644 index 000000000000..ee9cb2f2a36b --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/try_err.sol @@ -0,0 +1,34 @@ +contract C { + struct S { bool f; } + S s; + function ext() external {} + function f() internal returns (S storage r) + { + try this.ext() { } + catch (bytes memory) { r = s; } + } + function g() internal returns (S storage r) + { + try this.ext() { r = s; } + catch (bytes memory) { } + } + function h() internal returns (S storage r) + { + try this.ext() {} + catch Error (string memory) { r = s; } + catch (bytes memory) { r = s; } + } + function i() internal returns (S storage r) + { + try this.ext() { r = s; } + catch (bytes memory) { return r; } + r = s; + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// TypeError: (113-124): This variable is of storage pointer type and can be returned without prior assignment. +// TypeError: (240-251): This variable is of storage pointer type and can be returned without prior assignment. +// TypeError: (367-378): This variable is of storage pointer type and can be returned without prior assignment. +// TypeError: (631-632): This variable is of storage pointer type and can be accessed without prior assignment. diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/try_fine.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/try_fine.sol new file mode 100644 index 000000000000..94d4ec1ee47b --- /dev/null +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/try_fine.sol @@ -0,0 +1,24 @@ +contract C { + struct S { bool f; } + S s; + function ext() external { } + function f() internal returns (S storage r) + { + try this.ext() { r = s; } + catch (bytes memory) { r = s; } + } + function g() internal returns (S storage r) + { + try this.ext() { r = s; } + catch Error (string memory) { r = s; } + catch (bytes memory) { r = s; } + } + function h() internal returns (S storage r) + { + try this.ext() { } + catch (bytes memory) { } + r = s; + } +} +// ==== +// EVMVersion: >=byzantium \ No newline at end of file From 8e736a9f4982315dc36a47e24f23e8048d0fe880 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 5 Sep 2019 20:02:34 +0200 Subject: [PATCH 036/283] Type Checker for try/catch. --- libsolidity/analysis/ControlFlowBuilder.cpp | 2 +- libsolidity/analysis/NameAndTypeResolver.cpp | 12 ++ libsolidity/analysis/NameAndTypeResolver.h | 2 + libsolidity/analysis/ReferencesResolver.cpp | 2 +- libsolidity/analysis/StaticAnalyzer.cpp | 6 +- libsolidity/analysis/TypeChecker.cpp | 129 ++++++++++++++++++- libsolidity/analysis/TypeChecker.h | 1 + libsolidity/ast/AST.cpp | 25 ++-- libsolidity/ast/AST.h | 5 +- 9 files changed, 166 insertions(+), 18 deletions(-) diff --git a/libsolidity/analysis/ControlFlowBuilder.cpp b/libsolidity/analysis/ControlFlowBuilder.cpp index 6774b6e38f4b..85566b32d8cb 100644 --- a/libsolidity/analysis/ControlFlowBuilder.cpp +++ b/libsolidity/analysis/ControlFlowBuilder.cpp @@ -396,7 +396,7 @@ bool ControlFlowBuilder::visit(VariableDeclaration const& _variableDeclaration) _variableDeclaration.value().get() ); // Function arguments are considered to be immediately assigned as well (they are "externally assigned"). - else if (_variableDeclaration.isCallableParameter() && !_variableDeclaration.isReturnParameter()) + else if (_variableDeclaration.isCallableOrCatchParameter() && !_variableDeclaration.isReturnParameter()) m_currentNode->variableOccurrences.emplace_back( _variableDeclaration, VariableOccurrence::Kind::Assignment, diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 727dc5f352cb..a1a266db1dc7 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -624,6 +624,18 @@ void DeclarationRegistrationHelper::endVisit(FunctionDefinition&) closeCurrentScope(); } +bool DeclarationRegistrationHelper::visit(TryCatchClause& _tryCatchClause) +{ + _tryCatchClause.setScope(m_currentScope); + enterNewSubScope(_tryCatchClause); + return true; +} + +void DeclarationRegistrationHelper::endVisit(TryCatchClause&) +{ + closeCurrentScope(); +} + bool DeclarationRegistrationHelper::visit(ModifierDefinition& _modifier) { registerDeclaration(_modifier, true); diff --git a/libsolidity/analysis/NameAndTypeResolver.h b/libsolidity/analysis/NameAndTypeResolver.h index e5f5774ab74e..1f8d19419ffc 100644 --- a/libsolidity/analysis/NameAndTypeResolver.h +++ b/libsolidity/analysis/NameAndTypeResolver.h @@ -177,6 +177,8 @@ class DeclarationRegistrationHelper: private ASTVisitor bool visit(EnumValue& _value) override; bool visit(FunctionDefinition& _function) override; void endVisit(FunctionDefinition& _function) override; + bool visit(TryCatchClause& _tryCatchClause) override; + void endVisit(TryCatchClause& _tryCatchClause) override; bool visit(ModifierDefinition& _modifier) override; void endVisit(ModifierDefinition& _modifier) override; bool visit(FunctionTypeName& _funTypeName) override; diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index a1df47abece5..43095cb097b4 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -388,7 +388,7 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable) ", ", " or " ); - if (_variable.isCallableParameter()) + if (_variable.isCallableOrCatchParameter()) errorString += " for " + string(_variable.isReturnParameter() ? "return " : "") + diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 2a0aaddcba6d..01c218218c42 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -118,10 +118,12 @@ void StaticAnalyzer::endVisit(FunctionDefinition const&) for (auto const& var: m_localVarUseCount) if (var.second == 0) { - if (var.first.second->isCallableParameter()) + if (var.first.second->isCallableOrCatchParameter()) m_errorReporter.warning( var.first.second->location(), - "Unused function parameter. Remove or comment out the variable name to silence this warning." + "Unused " + + string(var.first.second->isTryCatchParameter() ? "try/catch" : "function") + + " parameter. Remove or comment out the variable name to silence this warning." ); else m_errorReporter.warning(var.first.second->location(), "Unused local variable."); diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index fcf81c2daaaf..0b31fbf95ac7 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -433,7 +433,7 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) // * or inside of a struct definition. if ( m_scope->isInterface() - && !_variable.isCallableParameter() + && !_variable.isCallableOrCatchParameter() && !m_insideStruct ) m_errorReporter.typeError(_variable.location(), "Variables cannot be declared in interfaces."); @@ -743,6 +743,133 @@ bool TypeChecker::visit(IfStatement const& _ifStatement) return false; } +void TypeChecker::endVisit(TryStatement const& _tryStatement) +{ + FunctionCall const* externalCall = dynamic_cast(&_tryStatement.externalCall()); + if (!externalCall || externalCall->annotation().kind != FunctionCallKind::FunctionCall) + { + m_errorReporter.typeError( + _tryStatement.externalCall().location(), + "Try can only be used with external function calls and contract creation calls." + ); + return; + } + + FunctionType const& functionType = dynamic_cast(*externalCall->expression().annotation().type); + if ( + functionType.kind() != FunctionType::Kind::External && + functionType.kind() != FunctionType::Kind::Creation && + functionType.kind() != FunctionType::Kind::DelegateCall + ) + { + m_errorReporter.typeError( + _tryStatement.externalCall().location(), + "Try can only be used with external function calls and contract creation calls." + ); + return; + } + + externalCall->annotation().tryCall = true; + + solAssert(_tryStatement.clauses().size() >= 2, ""); + solAssert(_tryStatement.clauses().front(), ""); + + TryCatchClause const& successClause = *_tryStatement.clauses().front(); + if (successClause.parameters()) + { + TypePointers returnTypes = + m_evmVersion.supportsReturndata() ? + functionType.returnParameterTypes() : + functionType.returnParameterTypesWithoutDynamicTypes(); + std::vector> const& parameters = + successClause.parameters()->parameters(); + if (returnTypes.size() != parameters.size()) + m_errorReporter.typeError( + successClause.location(), + "Function returns " + + to_string(functionType.returnParameterTypes().size()) + + " values, but returns clause has " + + to_string(parameters.size()) + + " variables." + ); + size_t len = min(returnTypes.size(), parameters.size()); + for (size_t i = 0; i < len; ++i) + { + solAssert(returnTypes[i], ""); + if (parameters[i] && *parameters[i]->annotation().type != *returnTypes[i]) + m_errorReporter.typeError( + parameters[i]->location(), + "Invalid type, expected " + + returnTypes[i]->toString(false) + + " but got " + + parameters[i]->annotation().type->toString() + + "." + ); + } + } + + TryCatchClause const* errorClause = nullptr; + TryCatchClause const* lowLevelClause = nullptr; + for (size_t i = 1; i < _tryStatement.clauses().size(); ++i) + { + TryCatchClause const& clause = *_tryStatement.clauses()[i]; + if (clause.errorName() == "") + { + if (lowLevelClause) + m_errorReporter.typeError( + clause.location(), + SecondarySourceLocation{}.append("The first clause is here:", lowLevelClause->location()), + "This try statement already has a low-level catch clause." + ); + lowLevelClause = &clause; + if (clause.parameters() && !clause.parameters()->parameters().empty()) + { + if ( + clause.parameters()->parameters().size() != 1 || + *clause.parameters()->parameters().front()->type() != *TypeProvider::bytesMemory() + ) + m_errorReporter.typeError(clause.location(), "Expected `catch (bytes memory ...) { ... }` or `catch { ... }`."); + if (!m_evmVersion.supportsReturndata()) + m_errorReporter.typeError( + clause.location(), + "This catch clause type cannot be used on the selected EVM version (" + + m_evmVersion.name() + + "). You need at least a Byzantium-compatible EVM or use `catch { ... }`." + ); + } + } + else if (clause.errorName() == "Error") + { + if (!m_evmVersion.supportsReturndata()) + m_errorReporter.typeError( + clause.location(), + "This catch clause type cannot be used on the selected EVM version (" + + m_evmVersion.name() + + "). You need at least a Byzantium-compatible EVM or use `catch { ... }`." + ); + + if (errorClause) + m_errorReporter.typeError( + clause.location(), + SecondarySourceLocation{}.append("The first clause is here:", errorClause->location()), + "This try statement already has an \"Error\" catch clause." + ); + errorClause = &clause; + if ( + !clause.parameters() || + clause.parameters()->parameters().size() != 1 || + *clause.parameters()->parameters().front()->type() != *TypeProvider::stringMemory() + ) + m_errorReporter.typeError(clause.location(), "Expected `catch Error(string memory ...) { ... }`."); + } + else + m_errorReporter.typeError( + clause.location(), + "Invalid catch clause name. Expected either `catch (...)` or `catch Error(...)`." + ); + } +} + bool TypeChecker::visit(WhileStatement const& _whileStatement) { expectType(_whileStatement.condition(), *TypeProvider::boolean()); diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index c962ad2ed80b..9e5d46d94a5f 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -120,6 +120,7 @@ class TypeChecker: private ASTConstVisitor void endVisit(FunctionTypeName const& _funType) override; bool visit(InlineAssembly const& _inlineAssembly) override; bool visit(IfStatement const& _ifStatement) override; + void endVisit(TryStatement const& _tryStatement) override; bool visit(WhileStatement const& _whileStatement) override; bool visit(ForStatement const& _forStatement) override; void endVisit(Return const& _return) override; diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 2fec31fdd487..cc834143c56d 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -452,12 +452,9 @@ bool VariableDeclaration::isLocalVariable() const dynamic_cast(s); } -bool VariableDeclaration::isCallableParameter() const +bool VariableDeclaration::isCallableOrCatchParameter() const { - // TODO Adjust for catch params. - // I think catch params should return true here. - // some of the error strings would need to be adjusted. - if (isReturnParameter() || dynamic_cast(scope())) + if (isReturnParameter() || isTryCatchParameter()) return true; vector> const* parameters = nullptr; @@ -476,8 +473,7 @@ bool VariableDeclaration::isCallableParameter() const bool VariableDeclaration::isLocalOrReturn() const { - // TODO adjust for catch params - return isReturnParameter() || (isLocalVariable() && !isCallableParameter()); + return isReturnParameter() || (isLocalVariable() && !isCallableOrCatchParameter()); } bool VariableDeclaration::isReturnParameter() const @@ -497,9 +493,14 @@ bool VariableDeclaration::isReturnParameter() const return false; } +bool VariableDeclaration::isTryCatchParameter() const +{ + return dynamic_cast(scope()); +} + bool VariableDeclaration::isExternalCallableParameter() const { - if (!isCallableParameter()) + if (!isCallableOrCatchParameter()) return false; if (auto const* callable = dynamic_cast(scope())) @@ -511,7 +512,7 @@ bool VariableDeclaration::isExternalCallableParameter() const bool VariableDeclaration::isInternalCallableParameter() const { - if (!isCallableParameter()) + if (!isCallableOrCatchParameter()) return false; if (auto const* funTypeName = dynamic_cast(scope())) @@ -523,7 +524,7 @@ bool VariableDeclaration::isInternalCallableParameter() const bool VariableDeclaration::isLibraryFunctionParameter() const { - if (!isCallableParameter()) + if (!isCallableOrCatchParameter()) return false; if (auto const* funDef = dynamic_cast(scope())) return dynamic_cast(*funDef->scope()).isLibrary(); @@ -559,10 +560,10 @@ set VariableDeclaration::allowedDataLocations() c locations.insert(Location::Storage); return locations; } - else if (isCallableParameter()) + else if (isCallableOrCatchParameter()) { set locations{ Location::Memory }; - if (isInternalCallableParameter() || isLibraryFunctionParameter()) + if (isInternalCallableParameter() || isLibraryFunctionParameter() || isTryCatchParameter()) locations.insert(Location::Storage); return locations; } diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index ce0eb5d62723..5742cc74e323 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -738,9 +738,12 @@ class VariableDeclaration: public Declaration /// (or function type name or event) or declared inside a function body. bool isLocalVariable() const; /// @returns true if this variable is a parameter or return parameter of a function. - bool isCallableParameter() const; + bool isCallableOrCatchParameter() const; /// @returns true if this variable is a return parameter of a function. bool isReturnParameter() const; + /// @returns true if this variable is a parameter of the success or failure clausse + /// of a try/catch statement. + bool isTryCatchParameter() const; /// @returns true if this variable is a local variable or return parameter. bool isLocalOrReturn() const; /// @returns true if this variable is a parameter (not return parameter) of an external function. From 70b796bd1afb02763f18a4bd9229b07c1f5caa6c Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 5 Sep 2019 20:02:58 +0200 Subject: [PATCH 037/283] Code generator for try/catch. --- libsolidity/codegen/ContractCompiler.cpp | 179 +++++++++++++++++++++ libsolidity/codegen/ContractCompiler.h | 3 + libsolidity/codegen/ExpressionCompiler.cpp | 51 ++++-- libsolidity/codegen/ExpressionCompiler.h | 5 +- 4 files changed, 226 insertions(+), 12 deletions(-) diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index a9c3990f8d2e..587b13446612 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -34,6 +34,8 @@ #include +#include + #include #include @@ -761,6 +763,183 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) return false; } +bool ContractCompiler::visit(TryStatement const& _tryStatement) +{ + StackHeightChecker checker(m_context); + CompilerContext::LocationSetter locationSetter(m_context, _tryStatement); + + compileExpression(_tryStatement.externalCall()); + unsigned returnSize = _tryStatement.externalCall().annotation().type->sizeOnStack(); + + // Stack: [ return values] + eth::AssemblyItem successTag = m_context.appendConditionalJump(); + + // Catch case. + m_context.adjustStackOffset(-returnSize); + + handleCatch(_tryStatement.clauses()); + + eth::AssemblyItem endTag = m_context.appendJumpToNew(); + + m_context << successTag; + m_context.adjustStackOffset(returnSize); + { + // Success case. + // Stack: return values + TryCatchClause const& successClause = *_tryStatement.clauses().front(); + if (successClause.parameters()) + { + vector exprTypes{_tryStatement.externalCall().annotation().type}; + if (auto tupleType = dynamic_cast(exprTypes.front())) + exprTypes = tupleType->components(); + vector> const& params = successClause.parameters()->parameters(); + solAssert(exprTypes.size() == params.size(), ""); + for (size_t i = 0; i < exprTypes.size(); ++i) + solAssert(params[i] && exprTypes[i] && *params[i]->annotation().type == *exprTypes[i], ""); + } + else + CompilerUtils(m_context).popStackSlots(returnSize); + + _tryStatement.clauses().front()->accept(*this); + } + + m_context << endTag; + checker.check(); + return false; +} + +void ContractCompiler::handleCatch(vector> const& _catchClauses) +{ + // Stack is empty. + ASTPointer structured{}; + ASTPointer fallback{}; + for (size_t i = 1; i < _catchClauses.size(); ++i) + if (_catchClauses[i]->errorName() == "Error") + structured = _catchClauses[i]; + else if (_catchClauses[i]->errorName().empty()) + fallback = _catchClauses[i]; + else + solAssert(false, ""); + + solAssert(_catchClauses.size() == size_t(1 + (structured ? 1 : 0) + (fallback ? 1 : 0)), ""); + + eth::AssemblyItem endTag = m_context.newTag(); + eth::AssemblyItem fallbackTag = m_context.newTag(); + if (structured) + { + solAssert( + structured->parameters() && + structured->parameters()->parameters().size() == 1 && + structured->parameters()->parameters().front() && + *structured->parameters()->parameters().front()->annotation().type == *TypeProvider::stringMemory(), + "" + ); + solAssert(m_context.evmVersion().supportsReturndata(), ""); + + string errorHash = FixedHash<4>(dev::keccak256("Error(string)")).hex(); + + // Try to decode the error message. + // If this fails, leaves 0 on the stack, otherwise the pointer to the data string. + m_context << u256(0); + m_context.appendInlineAssembly( + Whiskers(R"({ + data := mload(0x40) + mstore(data, 0) + for {} 1 {} { + if lt(returndatasize(), 0x44) { data := 0 break } + returndatacopy(0, 0, 4) + let sig := + if iszero(eq(sig, 0x)) { data := 0 break } + returndatacopy(data, 4, sub(returndatasize(), 4)) + let offset := mload(data) + if or( + gt(offset, 0xffffffffffffffff), + gt(add(offset, 0x24), returndatasize()) + ) { + data := 0 + break + } + let msg := add(data, offset) + let length := mload(msg) + if gt(length, 0xffffffffffffffff) { data := 0 break } + let end := add(add(msg, 0x20), length) + if gt(end, add(data, returndatasize())) { data := 0 break } + mstore(0x40, and(add(end, 0x1f), not(0x1f))) + data := msg + break + } + })") + ("ErrorSignature", errorHash) + ("getSig", + m_context.evmVersion().hasBitwiseShifting() ? + "shr(224, mload(0))" : + "div(mload(0), " + (u256(1) << 224).str() + ")" + ).render(), + {"data"} + ); + m_context << Instruction::DUP1; + AssemblyItem decodeSuccessTag = m_context.appendConditionalJump(); + m_context << Instruction::POP; + m_context.appendJumpTo(fallbackTag); + m_context.adjustStackOffset(1); + + m_context << decodeSuccessTag; + structured->accept(*this); + m_context.appendJumpTo(endTag); + } + m_context << fallbackTag; + if (fallback) + { + if (fallback->parameters()) + { + solAssert(m_context.evmVersion().supportsReturndata(), ""); + solAssert( + fallback->parameters()->parameters().size() == 1 && + fallback->parameters()->parameters().front() && + *fallback->parameters()->parameters().front()->annotation().type == *TypeProvider::bytesMemory(), + "" + ); + CompilerUtils(m_context).returnDataToArray(); + } + + fallback->accept(*this); + } + else + { + // re-throw + if (m_context.evmVersion().supportsReturndata()) + m_context.appendInlineAssembly(R"({ + returndatacopy(0, 0, returndatasize()) + revert(0, returndatasize()) + })"); + else + m_context.appendRevert(); + } + m_context << endTag; +} + +bool ContractCompiler::visit(TryCatchClause const& _clause) +{ + CompilerContext::LocationSetter locationSetter(m_context, _clause); + + unsigned varSize = 0; + + if (_clause.parameters()) + for (ASTPointer const& varDecl: _clause.parameters()->parameters() | boost::adaptors::reversed) + { + solAssert(varDecl, ""); + varSize += varDecl->annotation().type->sizeOnStack(); + m_context.addVariable(*varDecl, varSize); + } + + _clause.block().accept(*this); + + m_context.removeVariablesAboveStackHeight(m_context.stackHeight() - varSize); + CompilerUtils(m_context).popStackSlots(varSize); + + return false; +} + bool ContractCompiler::visit(IfStatement const& _ifStatement) { StackHeightChecker checker(m_context); diff --git a/libsolidity/codegen/ContractCompiler.h b/libsolidity/codegen/ContractCompiler.h index 86013eb87cbd..c781b44f8a8a 100644 --- a/libsolidity/codegen/ContractCompiler.h +++ b/libsolidity/codegen/ContractCompiler.h @@ -104,6 +104,9 @@ class ContractCompiler: private ASTConstVisitor bool visit(VariableDeclaration const& _variableDeclaration) override; bool visit(FunctionDefinition const& _function) override; bool visit(InlineAssembly const& _inlineAssembly) override; + bool visit(TryStatement const& _tryStatement) override; + void handleCatch(std::vector> const& _catchClauses); + bool visit(TryCatchClause const& _clause) override; bool visit(IfStatement const& _ifStatement) override; bool visit(WhileStatement const& _whileStatement) override; bool visit(ForStatement const& _forStatement) override; diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index bc4a6de8e903..2ee9db441f26 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -586,13 +586,15 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) m_context.adjustStackOffset(returnParametersSize - parameterSize - 1); break; } - case FunctionType::Kind::External: - case FunctionType::Kind::DelegateCall: case FunctionType::Kind::BareCall: case FunctionType::Kind::BareDelegateCall: case FunctionType::Kind::BareStaticCall: + solAssert(!_functionCall.annotation().tryCall, ""); + [[fallthrough]]; + case FunctionType::Kind::External: + case FunctionType::Kind::DelegateCall: _functionCall.expression().accept(*this); - appendExternalFunctionCall(function, arguments); + appendExternalFunctionCall(function, arguments, _functionCall.annotation().tryCall); break; case FunctionType::Kind::BareCallCode: solAssert(false, "Callcode has been removed."); @@ -620,6 +622,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) else m_context << u256(0); m_context << Instruction::CREATE; + solUnimplementedAssert(!_functionCall.annotation().tryCall, ""); // Check if zero (out of stack or not enough balance). m_context << Instruction::DUP1 << Instruction::ISZERO; // TODO: Can we bubble up here? There might be different reasons for failure, I think. @@ -675,7 +678,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) true, true ), - {} + {}, + false ); if (function.kind() == FunctionType::Kind::Transfer) { @@ -835,7 +839,8 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) m_context << contractAddresses.at(function.kind()); for (unsigned i = function.sizeOnStack(); i > 0; --i) m_context << swapInstruction(i); - appendExternalFunctionCall(function, arguments); + solAssert(!_functionCall.annotation().tryCall, ""); + appendExternalFunctionCall(function, arguments, false); break; } case FunctionType::Kind::ByteArrayPush: @@ -1964,7 +1969,8 @@ void ExpressionCompiler::appendShiftOperatorCode(Token _operator, Type const& _v void ExpressionCompiler::appendExternalFunctionCall( FunctionType const& _functionType, - vector> const& _arguments + vector> const& _arguments, + bool _tryCall ) { solAssert( @@ -2000,6 +2006,12 @@ void ExpressionCompiler::appendExternalFunctionCall( bool isDelegateCall = funKind == FunctionType::Kind::BareDelegateCall || funKind == FunctionType::Kind::DelegateCall; bool useStaticCall = funKind == FunctionType::Kind::BareStaticCall || (_functionType.stateMutability() <= StateMutability::View && m_context.evmVersion().hasStaticCall()); + if (_tryCall) + { + solAssert(!returnSuccessConditionAndReturndata, ""); + solAssert(!_functionType.isBareCall(), ""); + } + bool haveReturndatacopy = m_context.evmVersion().supportsReturndata(); unsigned retSize = 0; bool dynamicReturnSize = false; @@ -2171,17 +2183,27 @@ void ExpressionCompiler::appendExternalFunctionCall( (_functionType.gasSet() ? 1 : 0) + (!_functionType.isBareCall() ? 1 : 0); - if (returnSuccessConditionAndReturndata) - m_context << swapInstruction(remainsSize); - else + eth::AssemblyItem endTag = m_context.newTag(); + + if (!returnSuccessConditionAndReturndata && !_tryCall) { - //Propagate error condition (if CALL pushes 0 on stack). + // Propagate error condition (if CALL pushes 0 on stack). m_context << Instruction::ISZERO; m_context.appendConditionalRevert(true); } - + else + m_context << swapInstruction(remainsSize); utils().popStackSlots(remainsSize); + // Only success flag is remaining on stack. + + if (_tryCall) + { + m_context << Instruction::DUP1 << Instruction::ISZERO; + m_context.appendConditionalJumpTo(endTag); + m_context << Instruction::POP; + } + if (returnSuccessConditionAndReturndata) { // success condition is already there @@ -2243,6 +2265,13 @@ void ExpressionCompiler::appendExternalFunctionCall( utils().abiDecode(returnTypes, true); } + + if (_tryCall) + { + // Success branch will reach this, failure branch will directly jump to endTag. + m_context << u256(1); + m_context << endTag; + } } void ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType, Expression const& _expression) diff --git a/libsolidity/codegen/ExpressionCompiler.h b/libsolidity/codegen/ExpressionCompiler.h index 8bdb1479afe9..c29794858e6c 100644 --- a/libsolidity/codegen/ExpressionCompiler.h +++ b/libsolidity/codegen/ExpressionCompiler.h @@ -96,9 +96,12 @@ class ExpressionCompiler: private ASTConstVisitor /// @} /// Appends code to call a function of the given type with the given arguments. + /// @param _tryCall if true, this is the external call of a try statement. In that case, + /// returns success flag on top of stack and does not revert on failure. void appendExternalFunctionCall( FunctionType const& _functionType, - std::vector> const& _arguments + std::vector> const& _arguments, + bool _tryCall ); /// Appends code that evaluates a single expression and moves the result to memory. The memory offset is /// expected to be on the stack and is updated by this call. From b5d6d5fcf90b367bdf0180d1f50a861a4daaea8e Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 9 Sep 2019 23:10:36 +0200 Subject: [PATCH 038/283] Create. --- libsolidity/codegen/ExpressionCompiler.cpp | 18 ++++++++--- .../semanticTests/tryCatch/create.sol | 32 +++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 test/libsolidity/semanticTests/tryCatch/create.sol diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 2ee9db441f26..41595271f578 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -622,13 +622,21 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) else m_context << u256(0); m_context << Instruction::CREATE; - solUnimplementedAssert(!_functionCall.annotation().tryCall, ""); - // Check if zero (out of stack or not enough balance). - m_context << Instruction::DUP1 << Instruction::ISZERO; - // TODO: Can we bubble up here? There might be different reasons for failure, I think. - m_context.appendConditionalRevert(true); if (function.valueSet()) m_context << swapInstruction(1) << Instruction::POP; + // Check if zero (reverted) + m_context << Instruction::DUP1 << Instruction::ISZERO; + if (_functionCall.annotation().tryCall) + { + // If this is a try call, return "
1" in the success case and + // "0" in the error case. + AssemblyItem errorCase = m_context.appendConditionalJump(); + m_context << u256(1); + m_context << errorCase; + } + else + // TODO: Can we bubble up here? There might be different reasons for failure, I think. + m_context.appendConditionalRevert(true); break; } case FunctionType::Kind::SetGas: diff --git a/test/libsolidity/semanticTests/tryCatch/create.sol b/test/libsolidity/semanticTests/tryCatch/create.sol new file mode 100644 index 000000000000..e80f1944a2a9 --- /dev/null +++ b/test/libsolidity/semanticTests/tryCatch/create.sol @@ -0,0 +1,32 @@ +contract Reverts { + constructor(uint) public { revert("test message."); } +} +contract Succeeds { + constructor(uint) public { } +} + +contract C { + function f() public returns (Reverts x, uint, string memory txt) { + uint i = 3; + try new Reverts(i) returns (Reverts r) { + x = r; + txt = "success"; + } catch Error(string memory s) { + txt = s; + } + } + function g() public returns (Succeeds x, uint, string memory txt) { + uint i = 8; + try new Succeeds(i) returns (Succeeds r) { + x = r; + txt = "success"; + } catch Error(string memory s) { + txt = s; + } + } +} +// ==== +// EVMVersion: >=byzantium +// ---- +// f() -> 0, 0, 96, 13, "test message." +// g() -> 0xf01f7809444bd9a93a854361c6fae3f23d9e23db, 0, 96, 7, "success" From 9a42a9395502404390035336f85d8cbe1e0671cb Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Thu, 19 Sep 2019 20:09:24 +0200 Subject: [PATCH 039/283] Updates solc-js tests to 0.6.0. --- test/solcjsTests.sh | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/test/solcjsTests.sh b/test/solcjsTests.sh index 93eac32e532a..7c263d51f42a 100755 --- a/test/solcjsTests.sh +++ b/test/solcjsTests.sh @@ -39,8 +39,8 @@ VERSION="$2" DIR=$(mktemp -d) ( - echo "Preparing solc-js (master)..." - git clone --depth 1 --branch master https://github.com/ethereum/solc-js "$DIR" + echo "Preparing solc-js (master_060)..." + git clone --depth 1 --branch master_060 https://github.com/ethereum/solc-js "$DIR" cd "$DIR" # disable "prepublish" script which downloads the latest version # (we will replace it anyway and it is often incorrectly cached @@ -53,11 +53,6 @@ DIR=$(mktemp -d) rm -f soljson.js cp "$SOLJSON" soljson.js - # ensure to use always 0.5.0 sources - # FIXME: should be removed once the version bump in this repo is done - rm -rf test/DAO040 - cp -R test/DAO test/DAO040 - # Update version (needed for some tests) echo "Updating package.json to version $VERSION" npm version --allow-same-version --no-git-tag-version $VERSION From e3a29ffcd339c20fc41de8781ce58d58da887fc1 Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Fri, 20 Sep 2019 20:23:10 +0200 Subject: [PATCH 040/283] Updates tests to version 0.6.0. --- test/contracts/AuctionRegistrar.cpp | 2 +- test/contracts/FixedFeeRegistrar.cpp | 2 +- test/contracts/Wallet.cpp | 2 +- test/libsolidity/GasCosts.cpp | 6 +++--- .../semanticTests/uninitializedFunctionPointer/store2.sol | 2 +- test/libsolidity/semanticTests/viaYul/erc20.sol | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/contracts/AuctionRegistrar.cpp b/test/contracts/AuctionRegistrar.cpp index b643754e95ab..7e0f6e58caf1 100644 --- a/test/contracts/AuctionRegistrar.cpp +++ b/test/contracts/AuctionRegistrar.cpp @@ -43,7 +43,7 @@ namespace { static char const* registrarCode = R"DELIMITER( -pragma solidity >=0.4.0 <0.6.0; +pragma solidity >=0.4.0 <0.7.0; contract NameRegister { function addr(string memory _name) public view returns (address o_owner); diff --git a/test/contracts/FixedFeeRegistrar.cpp b/test/contracts/FixedFeeRegistrar.cpp index e82f389fc62b..4d8be54f0d82 100644 --- a/test/contracts/FixedFeeRegistrar.cpp +++ b/test/contracts/FixedFeeRegistrar.cpp @@ -53,7 +53,7 @@ static char const* registrarCode = R"DELIMITER( // @authors: // Gav Wood -pragma solidity >=0.4.0 <0.6.0; +pragma solidity >=0.4.0 <0.7.0; contract Registrar { event Changed(string indexed name); diff --git a/test/contracts/Wallet.cpp b/test/contracts/Wallet.cpp index d0cbb9956b6f..ed981f565c21 100644 --- a/test/contracts/Wallet.cpp +++ b/test/contracts/Wallet.cpp @@ -56,7 +56,7 @@ static char const* walletCode = R"DELIMITER( // some number (specified in constructor) of the set of owners (specified in the constructor, modifiable) before the // interior is executed. -pragma solidity >=0.4.0 <0.6.0; +pragma solidity >=0.4.0 <0.7.0; contract multiowned { diff --git a/test/libsolidity/GasCosts.cpp b/test/libsolidity/GasCosts.cpp index 977553286a6a..9e906f70bfcd 100644 --- a/test/libsolidity/GasCosts.cpp +++ b/test/libsolidity/GasCosts.cpp @@ -96,17 +96,17 @@ BOOST_AUTO_TEST_CASE(string_storage) compileAndRun(sourceCode); if (Options::get().evmVersion() <= EVMVersion::byzantium()) - CHECK_DEPLOY_GAS(134209, 130895); + CHECK_DEPLOY_GAS(134145, 130831); // This is only correct on >=Constantinople. else if (Options::get().useABIEncoderV2) { if (Options::get().optimizeYul) - CHECK_DEPLOY_GAS(127785, 127785); + CHECK_DEPLOY_GAS(127785, 127721); else CHECK_DEPLOY_GAS(151587, 135371); } else - CHECK_DEPLOY_GAS(126993, 119723); + CHECK_DEPLOY_GAS(126929, 119659); if (Options::get().evmVersion() >= EVMVersion::byzantium()) { diff --git a/test/libsolidity/semanticTests/uninitializedFunctionPointer/store2.sol b/test/libsolidity/semanticTests/uninitializedFunctionPointer/store2.sol index 9d37ebed4f29..527ec52c1484 100644 --- a/test/libsolidity/semanticTests/uninitializedFunctionPointer/store2.sol +++ b/test/libsolidity/semanticTests/uninitializedFunctionPointer/store2.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.7; +pragma solidity >=0.5.7 <0.7.0; contract InvalidTest { diff --git a/test/libsolidity/semanticTests/viaYul/erc20.sol b/test/libsolidity/semanticTests/viaYul/erc20.sol index 1cb7599a0a6a..6b524e0bf4be 100644 --- a/test/libsolidity/semanticTests/viaYul/erc20.sol +++ b/test/libsolidity/semanticTests/viaYul/erc20.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.5.0; +pragma solidity >=0.4.0 <0.7.0; contract ERC20 { event Transfer(address indexed from, address indexed to, uint256 value); From 8adde5abbe13b015b625862e3657d109ae6a48b5 Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Wed, 25 Sep 2019 15:59:52 +0200 Subject: [PATCH 041/283] Migrates solc-js test to ext. test infrastructure. solc-js commit: 9d9de6338729cf5fbd62f479d54b7097e8a7e395 --- .circleci/config.yml | 2 +- scripts/test_emscripten.sh | 4 +- test/externalTests.sh | 1 + test/externalTests/colony.sh | 4 +- test/externalTests/common.sh | 44 +- test/externalTests/gnosis.sh | 4 +- test/externalTests/solc-js/DAO/DAO.sol | 943 ++++++++++++++++++ .../solc-js/DAO/ManagedAccount.sol | 68 ++ test/externalTests/solc-js/DAO/Token.sol | 150 +++ .../solc-js/DAO/TokenCreation.sol | 155 +++ test/externalTests/solc-js/determinism.js | 45 + .../solc-js/solc-js.sh} | 65 +- test/externalTests/zeppelin.sh | 4 +- 13 files changed, 1440 insertions(+), 49 deletions(-) create mode 100644 test/externalTests/solc-js/DAO/DAO.sol create mode 100644 test/externalTests/solc-js/DAO/ManagedAccount.sol create mode 100644 test/externalTests/solc-js/DAO/Token.sol create mode 100644 test/externalTests/solc-js/DAO/TokenCreation.sol create mode 100644 test/externalTests/solc-js/determinism.js rename test/{solcjsTests.sh => externalTests/solc-js/solc-js.sh} (53%) diff --git a/.circleci/config.yml b/.circleci/config.yml index 35509a56ed1d..b7e427d3e50d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -551,7 +551,7 @@ jobs: command: | node --version npm --version - test/solcjsTests.sh /tmp/workspace/soljson.js $(cat /tmp/workspace/version.txt) + test/externalTests/solc-js/solc-js.sh /tmp/workspace/soljson.js $(cat /tmp/workspace/version.txt) t_ems_external_gnosis: docker: diff --git a/scripts/test_emscripten.sh b/scripts/test_emscripten.sh index 783a6406500a..13eeeebdee3a 100755 --- a/scripts/test_emscripten.sh +++ b/scripts/test_emscripten.sh @@ -39,6 +39,4 @@ SOLJSON="$REPO_ROOT/$BUILD_DIR/libsolc/soljson.js" VERSION=$("$REPO_ROOT"/scripts/get_version.sh) echo "Running solcjs tests...." -"$REPO_ROOT/test/solcjsTests.sh" "$SOLJSON" "$VERSION" -echo "Running external tests...." -"$REPO_ROOT/test/externalTests.sh" "$SOLJSON" +"$REPO_ROOT/test/externalTests/solc-js/solc-js.sh" "$SOLJSON" "$VERSION" diff --git a/test/externalTests.sh b/test/externalTests.sh index acac38629e28..d7ba829a728a 100755 --- a/test/externalTests.sh +++ b/test/externalTests.sh @@ -44,6 +44,7 @@ printTask "Running external tests..." $REPO_ROOT/externalTests/zeppelin.sh "$SOLJSON" $REPO_ROOT/externalTests/gnosis.sh "$SOLJSON" +$REPO_ROOT/externalTests/colony.sh "$SOLJSON" # Disabled temporarily as it needs to be updated to latest Truffle first. #test_truffle Gnosis https://github.com/axic/pm-contracts.git solidity-050 diff --git a/test/externalTests/colony.sh b/test/externalTests/colony.sh index 0e867c9975a5..2f95f71a8eea 100755 --- a/test/externalTests/colony.sh +++ b/test/externalTests/colony.sh @@ -32,7 +32,7 @@ function colony_test { OPTIMIZER_LEVEL=3 FORCE_ABIv2=false - setup https://github.com/JoinColony/colonyNetwork.git develop master + truffle_setup https://github.com/JoinColony/colonyNetwork.git develop run_install install_fn CONFIG=$(find_truffle_config) @@ -42,7 +42,7 @@ function colony_test git clone https://github.com/erak/dappsys-monolithic.git -b callvalue-payable-fix dappsys cd .. - run_test compile_fn test_fn + truffle_run_test compile_fn test_fn } external_test ColonyNetworks colony_test diff --git a/test/externalTests/common.sh b/test/externalTests/common.sh index d6574da4ddf4..6c427dddccbc 100644 --- a/test/externalTests/common.sh +++ b/test/externalTests/common.sh @@ -30,16 +30,40 @@ function verify_input fi } +function verify_version_input +{ + if [ -z "$1" ] || [ ! -f "$1" ] || [ -z "$2" ]; then + printError "Usage: $0 " + exit 1 + fi +} + +function setup +{ + local branch="$1" + + setup_solcjs "$DIR" "$SOLJSON" "$branch" "solc" + cd solc +} + function setup_solcjs { local dir="$1" local soljson="$2" + local branch="$3" + local path="$4" cd "$dir" printLog "Setting up solc-js..." - git clone --depth 1 -b v0.5.0 https://github.com/ethereum/solc-js.git solc + git clone --depth 1 -b "$branch" https://github.com/ethereum/solc-js.git "$path" + + cd "$path" + + # disable "prepublish" script which downloads the latest version + # (we will replace it anyway and it is often incorrectly cached + # on travis) + npm config set script.prepublish '' - cd solc npm install cp "$soljson" soljson.js SOLCVERSION=$(./solcjs --version) @@ -59,12 +83,12 @@ function download_project echo "Current commit hash: `git rev-parse HEAD`" } -function setup +function truffle_setup { local repo="$1" local branch="$2" - setup_solcjs "$DIR" "$SOLJSON" + setup_solcjs "$DIR" "$SOLJSON" "v0.5.0" "solc" download_project "$repo" "$branch" "$DIR" replace_version_pragmas @@ -187,6 +211,18 @@ function run_test local compile_fn="$1" local test_fn="$2" + printLog "Running compile function..." + $compile_fn + + printLog "Running test function..." + $test_fn +} + +function truffle_run_test +{ + local compile_fn="$1" + local test_fn="$2" + force_solc "$CONFIG" "$DIR" "$SOLJSON" printLog "Checking optimizer level..." diff --git a/test/externalTests/gnosis.sh b/test/externalTests/gnosis.sh index f86816fd0a85..ef5718b4eb4f 100755 --- a/test/externalTests/gnosis.sh +++ b/test/externalTests/gnosis.sh @@ -31,13 +31,13 @@ function test_fn { npm test; } function gnosis_safe_test { OPTIMIZER_LEVEL=1 - setup https://github.com/gnosis/safe-contracts.git development + truffle_setup https://github.com/gnosis/safe-contracts.git development run_install install_fn CONFIG=$(find_truffle_config) replace_libsolc_call - run_test compile_fn test_fn + truffle_run_test compile_fn test_fn } external_test Gnosis-Safe gnosis_safe_test diff --git a/test/externalTests/solc-js/DAO/DAO.sol b/test/externalTests/solc-js/DAO/DAO.sol new file mode 100644 index 000000000000..3aed551c6bcf --- /dev/null +++ b/test/externalTests/solc-js/DAO/DAO.sol @@ -0,0 +1,943 @@ +/* +This file is part of the DAO. + +The DAO is free software: you can redistribute it and/or modify +it under the terms of the GNU lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The DAO 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 lesser General Public License for more details. + +You should have received a copy of the GNU lesser General Public License +along with the DAO. If not, see . +*/ + + +/* +Standard smart contract for a Decentralized Autonomous Organization (DAO) +to automate organizational governance and decision-making. +*/ + +import "./TokenCreation.sol"; +import "./ManagedAccount.sol"; + +contract DAOInterface { + + // The amount of days for which people who try to participate in the + // creation by calling the fallback function will still get their ether back + uint constant creationGracePeriod = 40 days; + // The minimum debate period that a generic proposal can have + uint constant minProposalDebatePeriod = 2 weeks; + // The minimum debate period that a split proposal can have + uint constant minSplitDebatePeriod = 1 weeks; + // Period of days inside which it's possible to execute a DAO split + uint constant splitExecutionPeriod = 27 days; + // Period of time after which the minimum Quorum is halved + uint constant quorumHalvingPeriod = 25 weeks; + // Period after which a proposal is closed + // (used in the case `executeProposal` fails because it throws) + uint constant executeProposalPeriod = 10 days; + // Denotes the maximum proposal deposit that can be given. It is given as + // a fraction of total Ether spent plus balance of the DAO + uint constant maxDepositDivisor = 100; + + // Proposals to spend the DAO's ether or to choose a new Curator + Proposal[] public proposals; + // The quorum needed for each proposal is partially calculated by + // totalSupply / minQuorumDivisor + uint public minQuorumDivisor; + // The unix time of the last time quorum was reached on a proposal + uint public lastTimeMinQuorumMet; + + // Address of the curator + address payable public curator; + // The whitelist: List of addresses the DAO is allowed to send ether to + mapping (address => bool) public allowedRecipients; + + // Tracks the addresses that own Reward Tokens. Those addresses can only be + // DAOs that have split from the original DAO. Conceptually, Reward Tokens + // represent the proportion of the rewards that the DAO has the right to + // receive. These Reward Tokens are generated when the DAO spends ether. + mapping (address => uint) public rewardToken; + // Total supply of rewardToken + uint public totalRewardToken; + + // The account used to manage the rewards which are to be distributed to the + // DAO Token Holders of this DAO + ManagedAccount public rewardAccount; + + // The account used to manage the rewards which are to be distributed to + // any DAO that holds Reward Tokens + ManagedAccount public DAOrewardAccount; + + // Amount of rewards (in wei) already paid out to a certain DAO + mapping (address => uint) public DAOpaidOut; + + // Amount of rewards (in wei) already paid out to a certain address + mapping (address => uint) public paidOut; + // Map of addresses blocked during a vote (not allowed to transfer DAO + // tokens). The address points to the proposal ID. + mapping (address => uint) public blocked; + + // The minimum deposit (in wei) required to submit any proposal that is not + // requesting a new Curator (no deposit is required for splits) + uint public proposalDeposit; + + // the accumulated sum of all current proposal deposits + uint sumOfProposalDeposits; + + // Contract that is able to create a new DAO (with the same code as + // this one), used for splits + DAO_Creator public daoCreator; + + // A proposal with `newCurator == false` represents a transaction + // to be issued by this DAO + // A proposal with `newCurator == true` represents a DAO split + struct Proposal { + // The address where the `amount` will go to if the proposal is accepted + // or if `newCurator` is true, the proposed Curator of + // the new DAO). + address payable recipient; + // The amount to transfer to `recipient` if the proposal is accepted. + uint amount; + // A plain text description of the proposal + string description; + // A unix timestamp, denoting the end of the voting period + uint votingDeadline; + // True if the proposal's votes have yet to be counted, otherwise False + bool open; + // True if quorum has been reached, the votes have been counted, and + // the majority said yes + bool proposalPassed; + // A hash to check validity of a proposal + bytes32 proposalHash; + // Deposit in wei the creator added when submitting their proposal. It + // is taken from the msg.value of a newProposal call. + uint proposalDeposit; + // True if this proposal is to assign a new Curator + bool newCurator; + // Data needed for splitting the DAO + SplitData[] splitData; + // Number of Tokens in favor of the proposal + uint yea; + // Number of Tokens opposed to the proposal + uint nay; + // Simple mapping to check if a shareholder has voted for it + mapping (address => bool) votedYes; + // Simple mapping to check if a shareholder has voted against it + mapping (address => bool) votedNo; + // Address of the shareholder who created the proposal + address payable creator; + } + + // Used only in the case of a newCurator proposal. + struct SplitData { + // The balance of the current DAO minus the deposit at the time of split + uint splitBalance; + // The total amount of DAO Tokens in existence at the time of split. + uint totalSupply; + // Amount of Reward Tokens owned by the DAO at the time of split. + uint rewardToken; + // The new DAO contract created at the time of split. + DAO newDAO; + } + + /// @dev Constructor setting the Curator and the address + /// for the contract able to create another DAO as well as the parameters + /// for the DAO Token Creation + /// @param _curator The Curator + /// @param _daoCreator The contract able to (re)create this DAO + /// @param _proposalDeposit The deposit to be paid for a regular proposal + /// @param _minTokensToCreate Minimum required wei-equivalent tokens + /// to be created for a successful DAO Token Creation + /// @param _closingTime Date (in Unix time) of the end of the DAO Token Creation + /// @param _privateCreation If zero the DAO Token Creation is open to public, a + /// non-zero address means that the DAO Token Creation is only for the address + /// @param _tokenName The name that the DAO's token will have + /// @param _tokenSymbol The ticker symbol that this DAO token should have + /// @param _decimalPlaces The number of decimal places that the token is + /// counted from. + // This is the constructor: it can not be overloaded so it is commented out + // function DAO( + // address payable _curator, + // DAO_Creator _daoCreator, + // uint _proposalDeposit, + // uint _minTokensToCreate, + // uint _closingTime, + // address _privateCreation + // string _tokenName, + // string _tokenSymbol, + // uint8 _decimalPlaces + // ); + + /// @notice Create Token with `msg.sender` as the beneficiary + function () external payable; + + + /// @dev This function is used to send ether back + /// to the DAO, it can also be used to receive payments that should not be + /// counted as rewards (donations, grants, etc.) + /// @return Whether the DAO received the ether successfully + function receiveEther() public returns (bool); + + /// @notice `msg.sender` creates a proposal to send `_amount` Wei to + /// `_recipient` with the transaction data `_transactionData`. If + /// `_newCurator` is true, then this is a proposal that splits the + /// DAO and sets `_recipient` as the new DAO's Curator. + /// @param _recipient Address of the recipient of the proposed transaction + /// @param _amount Amount of wei to be sent with the proposed transaction + /// @param _description String describing the proposal + /// @param _transactionData Data of the proposed transaction + /// @param _debatingPeriod Time used for debating a proposal, at least 2 + /// weeks for a regular proposal, 10 days for new Curator proposal + /// @param _newCurator Bool defining whether this proposal is about + /// a new Curator or not + /// @return The proposal ID. Needed for voting on the proposal + function newProposal( + address payable _recipient, + uint _amount, + string memory _description, + bytes memory _transactionData, + uint _debatingPeriod, + bool _newCurator + ) public payable returns (uint _proposalID); + + /// @notice Check that the proposal with the ID `_proposalID` matches the + /// transaction which sends `_amount` with data `_transactionData` + /// to `_recipient` + /// @param _proposalID The proposal ID + /// @param _recipient The recipient of the proposed transaction + /// @param _amount The amount of wei to be sent in the proposed transaction + /// @param _transactionData The data of the proposed transaction + /// @return Whether the proposal ID matches the transaction data or not + function checkProposalCode( + uint _proposalID, + address payable _recipient, + uint _amount, + bytes memory _transactionData + ) public view returns (bool _codeChecksOut); + + /// @notice Vote on proposal `_proposalID` with `_supportsProposal` + /// @param _proposalID The proposal ID + /// @param _supportsProposal Yes/No - support of the proposal + /// @return The vote ID. + function vote( + uint _proposalID, + bool _supportsProposal + ) public returns (uint _voteID); + + /// @notice Checks whether proposal `_proposalID` with transaction data + /// `_transactionData` has been voted for or rejected, and executes the + /// transaction in the case it has been voted for. + /// @param _proposalID The proposal ID + /// @param _transactionData The data of the proposed transaction + /// @return Whether the proposed transaction has been executed or not + function executeProposal( + uint _proposalID, + bytes memory _transactionData + ) public returns (bool _success); + + /// @notice ATTENTION! I confirm to move my remaining ether to a new DAO + /// with `_newCurator` as the new Curator, as has been + /// proposed in proposal `_proposalID`. This will burn my tokens. This can + /// not be undone and will split the DAO into two DAO's, with two + /// different underlying tokens. + /// @param _proposalID The proposal ID + /// @param _newCurator The new Curator of the new DAO + /// @dev This function, when called for the first time for this proposal, + /// will create a new DAO and send the sender's portion of the remaining + /// ether and Reward Tokens to the new DAO. It will also burn the DAO Tokens + /// of the sender. + function splitDAO( + uint _proposalID, + address payable _newCurator + ) public returns (bool _success); + + /// @dev can only be called by the DAO itself through a proposal + /// updates the contract of the DAO by sending all ether and rewardTokens + /// to the new DAO. The new DAO needs to be approved by the Curator + /// @param _newContract the address of the new contract + function newContract(address payable _newContract) public; + + + /// @notice Add a new possible recipient `_recipient` to the whitelist so + /// that the DAO can send transactions to them (using proposals) + /// @param _recipient New recipient address + /// @dev Can only be called by the current Curator + /// @return Whether successful or not + function changeAllowedRecipients(address _recipient, bool _allowed) external returns (bool _success); + + + /// @notice Change the minimum deposit required to submit a proposal + /// @param _proposalDeposit The new proposal deposit + /// @dev Can only be called by this DAO (through proposals with the + /// recipient being this DAO itself) + function changeProposalDeposit(uint _proposalDeposit) external; + + /// @notice Move rewards from the DAORewards managed account + /// @param _toMembers If true rewards are moved to the actual reward account + /// for the DAO. If not then it's moved to the DAO itself + /// @return Whether the call was successful + function retrieveDAOReward(bool _toMembers) external returns (bool _success); + + /// @notice Get my portion of the reward that was sent to `rewardAccount` + /// @return Whether the call was successful + function getMyReward() public returns (bool _success); + + /// @notice Withdraw `_account`'s portion of the reward from `rewardAccount` + /// to `_account`'s balance + /// @return Whether the call was successful + function withdrawRewardFor(address payable _account) internal returns (bool _success); + + /// @notice Send `_amount` tokens to `_to` from `msg.sender`. Prior to this + /// getMyReward() is called. + /// @param _to The address of the recipient + /// @param _amount The amount of tokens to be transfered + /// @return Whether the transfer was successful or not + function transferWithoutReward(address _to, uint256 _amount) public returns (bool success); + + /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it + /// is approved by `_from`. Prior to this getMyReward() is called. + /// @param _from The address of the sender + /// @param _to The address of the recipient + /// @param _amount The amount of tokens to be transfered + /// @return Whether the transfer was successful or not + function transferFromWithoutReward( + address payable _from, + address _to, + uint256 _amount + ) public returns (bool success); + + /// @notice Doubles the 'minQuorumDivisor' in the case quorum has not been + /// achieved in 52 weeks + /// @return Whether the change was successful or not + function halveMinQuorum() public returns (bool _success); + + /// @return total number of proposals ever created + function numberOfProposals() public view returns (uint _numberOfProposals); + + /// @param _proposalID Id of the new curator proposal + /// @return Address of the new DAO + function getNewDAOAddress(uint _proposalID) public view returns (address _newDAO); + + /// @param _account The address of the account which is checked. + /// @return Whether the account is blocked (not allowed to transfer tokens) or not. + function isBlocked(address _account) internal returns (bool); + + /// @notice If the caller is blocked by a proposal whose voting deadline + /// has exprired then unblock him. + /// @return Whether the account is blocked (not allowed to transfer tokens) or not. + function unblockMe() public returns (bool); + + event ProposalAdded( + uint indexed proposalID, + address recipient, + uint amount, + bool newCurator, + string description + ); + event Voted(uint indexed proposalID, bool position, address indexed voter); + event ProposalTallied(uint indexed proposalID, bool result, uint quorum); + event NewCurator(address indexed _newCurator); + event AllowedRecipientChanged(address indexed _recipient, bool _allowed); +} + +// The DAO contract itself +contract DAO is DAOInterface, Token, TokenCreation { + + // Modifier that allows only shareholders to vote and create new proposals + modifier onlyTokenholders { + if (balanceOf(msg.sender) == 0) revert(); + _; + } + + constructor( + address payable _curator, + DAO_Creator _daoCreator, + uint _proposalDeposit, + uint _minTokensToCreate, + uint _closingTime, + address _privateCreation, + string memory _tokenName, + string memory _tokenSymbol, + uint8 _decimalPlaces + ) TokenCreation( + _minTokensToCreate, + _closingTime, + _privateCreation, + _tokenName, + _tokenSymbol, + _decimalPlaces) public { + + curator = _curator; + daoCreator = _daoCreator; + proposalDeposit = _proposalDeposit; + rewardAccount = new ManagedAccount(address(this), false); + DAOrewardAccount = new ManagedAccount(address(this), false); + if (address(rewardAccount) == 0x0000000000000000000000000000000000000000) + revert(); + if (address(DAOrewardAccount) == 0x0000000000000000000000000000000000000000) + revert(); + lastTimeMinQuorumMet = now; + minQuorumDivisor = 5; // sets the minimal quorum to 20% + proposals.length = 1; // avoids a proposal with ID 0 because it is used + + allowedRecipients[address(this)] = true; + allowedRecipients[curator] = true; + } + + function () external payable { + if (now < closingTime + creationGracePeriod && msg.sender != address(extraBalance)) + createTokenProxy(msg.sender); + else + receiveEther(); + } + + + function receiveEther() public returns (bool) { + return true; + } + + + function newProposal( + address payable _recipient, + uint _amount, + string memory _description, + bytes memory _transactionData, + uint _debatingPeriod, + bool _newCurator + ) onlyTokenholders public payable returns (uint _proposalID) { + + // Sanity check + if (_newCurator && ( + _amount != 0 + || _transactionData.length != 0 + || _recipient == curator + || msg.value > 0 + || _debatingPeriod < minSplitDebatePeriod)) { + revert(); + } else if ( + !_newCurator + && (!isRecipientAllowed(_recipient) || (_debatingPeriod < minProposalDebatePeriod)) + ) { + revert(); + } + + if (_debatingPeriod > 8 weeks) + revert(); + + if (!isFueled + || now < closingTime + || (msg.value < proposalDeposit && !_newCurator)) { + + revert(); + } + + if (now + _debatingPeriod < now) // prevents overflow + revert(); + + // to prevent a 51% attacker to convert the ether into deposit + if (msg.sender == address(this)) + revert(); + + // to prevent curator from halving quorum before first proposal + if (proposals.length == 1) // initial length is 1 (see constructor) + lastTimeMinQuorumMet = now; + + _proposalID = proposals.length++; + Proposal storage p = proposals[_proposalID]; + p.recipient = _recipient; + p.amount = _amount; + p.description = _description; + p.proposalHash = keccak256(abi.encodePacked(_recipient, _amount, _transactionData)); + p.votingDeadline = now + _debatingPeriod; + p.open = true; + //p.proposalPassed = False; // that's default + p.newCurator = _newCurator; + if (_newCurator) + p.splitData.length++; + p.creator = msg.sender; + p.proposalDeposit = msg.value; + + sumOfProposalDeposits += msg.value; + + emit ProposalAdded( + _proposalID, + _recipient, + _amount, + _newCurator, + _description + ); + } + + + function checkProposalCode( + uint _proposalID, + address payable _recipient, + uint _amount, + bytes memory _transactionData + ) public view returns (bool _codeChecksOut) { + Proposal storage p = proposals[_proposalID]; + return p.proposalHash == keccak256(abi.encodePacked(_recipient, _amount, _transactionData)); + } + + + function vote( + uint _proposalID, + bool _supportsProposal + ) onlyTokenholders public returns (uint _voteID) { + + Proposal storage p = proposals[_proposalID]; + if (p.votedYes[msg.sender] + || p.votedNo[msg.sender] + || now >= p.votingDeadline) { + + revert(); + } + + if (_supportsProposal) { + p.yea += balances[msg.sender]; + p.votedYes[msg.sender] = true; + } else { + p.nay += balances[msg.sender]; + p.votedNo[msg.sender] = true; + } + + if (blocked[msg.sender] == 0) { + blocked[msg.sender] = _proposalID; + } else if (p.votingDeadline > proposals[blocked[msg.sender]].votingDeadline) { + // this proposal's voting deadline is further into the future than + // the proposal that blocks the sender so make it the blocker + blocked[msg.sender] = _proposalID; + } + + emit Voted(_proposalID, _supportsProposal, msg.sender); + } + + + function executeProposal( + uint _proposalID, + bytes memory _transactionData + ) public returns (bool _success) { + + Proposal storage p = proposals[_proposalID]; + + uint waitPeriod = p.newCurator + ? splitExecutionPeriod + : executeProposalPeriod; + // If we are over deadline and waiting period, assert proposal is closed + if (p.open && now > p.votingDeadline + waitPeriod) { + closeProposal(_proposalID); + return false; + } + + // Check if the proposal can be executed + if (now < p.votingDeadline // has the voting deadline arrived? + // Have the votes been counted? + || !p.open + || p.proposalPassed // anyone trying to call us recursively? + // Does the transaction code match the proposal? + || p.proposalHash != keccak256(abi.encodePacked(p.recipient, p.amount, _transactionData))) { + + revert(); + } + + // If the curator removed the recipient from the whitelist, close the proposal + // in order to free the deposit and allow unblocking of voters + if (!isRecipientAllowed(p.recipient)) { + closeProposal(_proposalID); + p.creator.send(p.proposalDeposit); + return false; + } + + bool proposalCheck = true; + + if (p.amount > actualBalance()) + proposalCheck = false; + + uint quorum = p.yea + p.nay; + + // require 53% for calling newContract() + if (_transactionData.length >= 4 && _transactionData[0] == 0x68 + && _transactionData[1] == 0x37 && _transactionData[2] == 0xff + && _transactionData[3] == 0x1e + && quorum < minQuorum(actualBalance() + rewardToken[address(this)])) { + + proposalCheck = false; + } + + if (quorum >= minQuorum(p.amount)) { + if (!p.creator.send(p.proposalDeposit)) + revert(); + + lastTimeMinQuorumMet = now; + // set the minQuorum to 20% again, in the case it has been reached + if (quorum > totalSupply / 5) + minQuorumDivisor = 5; + } + + // Execute result + if (quorum >= minQuorum(p.amount) && p.yea > p.nay && proposalCheck) { + // we are setting this here before the CALL() value transfer to + // assure that in the case of a malicious recipient contract trying + // to call executeProposal() recursively money can't be transferred + // multiple times out of the DAO + p.proposalPassed = true; + + (bool success,) = p.recipient.call.value(p.amount)(_transactionData); + if (!success) + revert(); + + _success = true; + + // only create reward tokens when ether is not sent to the DAO itself and + // related addresses. Proxy addresses should be forbidden by the curator. + if (p.recipient != address(this) && p.recipient != address(rewardAccount) + && p.recipient != address(DAOrewardAccount) + && p.recipient != address(extraBalance) + && p.recipient != address(curator)) { + + rewardToken[address(this)] += p.amount; + totalRewardToken += p.amount; + } + } + + closeProposal(_proposalID); + + // Initiate event + emit ProposalTallied(_proposalID, _success, quorum); + } + + + function closeProposal(uint _proposalID) internal { + Proposal storage p = proposals[_proposalID]; + if (p.open) + sumOfProposalDeposits -= p.proposalDeposit; + p.open = false; + } + + function splitDAO( + uint _proposalID, + address payable _newCurator + ) onlyTokenholders public returns (bool _success) { + + Proposal storage p = proposals[_proposalID]; + + // Sanity check + + if (now < p.votingDeadline // has the voting deadline arrived? + //The request for a split expires XX days after the voting deadline + || now > p.votingDeadline + splitExecutionPeriod + // Does the new Curator address match? + || p.recipient != _newCurator + // Is it a new curator proposal? + || !p.newCurator + // Have you voted for this split? + || !p.votedYes[msg.sender] + // Did you already vote on another proposal? + || (blocked[msg.sender] != _proposalID && blocked[msg.sender] != 0) ) { + + revert(); + } + + // If the new DAO doesn't exist yet, create the new DAO and store the + // current split data + if (address(p.splitData[0].newDAO) == 0x0000000000000000000000000000000000000000) { + p.splitData[0].newDAO = createNewDAO(_newCurator); + // Call depth limit reached, etc. + if (address(p.splitData[0].newDAO) == 0x0000000000000000000000000000000000000000) + revert(); + // should never happen + if (address(this).balance < sumOfProposalDeposits) + revert(); + p.splitData[0].splitBalance = actualBalance(); + p.splitData[0].rewardToken = rewardToken[address(this)]; + p.splitData[0].totalSupply = totalSupply; + p.proposalPassed = true; + } + + // Move ether and assign new Tokens + uint fundsToBeMoved = + (balances[msg.sender] * p.splitData[0].splitBalance) / + p.splitData[0].totalSupply; + if (p.splitData[0].newDAO.createTokenProxy.value(fundsToBeMoved)(msg.sender) == false) + revert(); + + + // Assign reward rights to new DAO + uint rewardTokenToBeMoved = + (balances[msg.sender] * p.splitData[0].rewardToken) / + p.splitData[0].totalSupply; + + uint paidOutToBeMoved = DAOpaidOut[address(this)] * rewardTokenToBeMoved / + rewardToken[address(this)]; + + rewardToken[address(p.splitData[0].newDAO)] += rewardTokenToBeMoved; + if (rewardToken[address(this)] < rewardTokenToBeMoved) + revert(); + rewardToken[address(this)] -= rewardTokenToBeMoved; + + DAOpaidOut[address(p.splitData[0].newDAO)] += paidOutToBeMoved; + if (DAOpaidOut[address(this)] < paidOutToBeMoved) + revert(); + DAOpaidOut[address(this)] -= paidOutToBeMoved; + + // Burn DAO Tokens + emit Transfer(msg.sender, 0x0000000000000000000000000000000000000000, balances[msg.sender]); + withdrawRewardFor(msg.sender); // be nice, and get his rewards + totalSupply -= balances[msg.sender]; + balances[msg.sender] = 0; + paidOut[msg.sender] = 0; + return true; + } + + function newContract(address payable _newContract) public { + if (msg.sender != address(this) || !allowedRecipients[_newContract]) return; + // move all ether + (bool success,) = _newContract.call.value(address(this).balance)(""); + if (!success) { + revert(); + } + + //move all reward tokens + rewardToken[_newContract] += rewardToken[address(this)]; + rewardToken[address(this)] = 0; + DAOpaidOut[_newContract] += DAOpaidOut[address(this)]; + DAOpaidOut[address(this)] = 0; + } + + + function retrieveDAOReward(bool _toMembers) external returns (bool _success) { + DAO dao = DAO(msg.sender); + + if ((rewardToken[msg.sender] * DAOrewardAccount.accumulatedInput()) / + totalRewardToken < DAOpaidOut[msg.sender]) + revert(); + + uint reward = + (rewardToken[msg.sender] * DAOrewardAccount.accumulatedInput()) / + totalRewardToken - DAOpaidOut[msg.sender]; + + reward = address(DAOrewardAccount).balance < reward ? address(DAOrewardAccount).balance : reward; + + if(_toMembers) { + if (!DAOrewardAccount.payOut(address(dao.rewardAccount()), reward)) + revert(); + } + else { + if (!DAOrewardAccount.payOut(address(dao), reward)) + revert(); + } + DAOpaidOut[msg.sender] += reward; + return true; + } + + function getMyReward() public returns (bool _success) { + return withdrawRewardFor(msg.sender); + } + + + function withdrawRewardFor(address payable _account) noEther internal returns (bool _success) { + if ((balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply < paidOut[_account]) + revert(); + + uint reward = + (balanceOf(_account) * rewardAccount.accumulatedInput()) / totalSupply - paidOut[_account]; + + reward = address(rewardAccount).balance < reward ? address(rewardAccount).balance : reward; + + if (!rewardAccount.payOut(_account, reward)) + revert(); + paidOut[_account] += reward; + return true; + } + + + function transfer(address _to, uint256 _value) public returns (bool success) { + if (isFueled + && now > closingTime + && !isBlocked(msg.sender) + && _to != address(this) + && transferPaidOut(msg.sender, _to, _value) + && super.transfer(_to, _value)) { + + return true; + } else { + revert(); + } + } + + + function transferWithoutReward(address _to, uint256 _value) public returns (bool success) { + if (!getMyReward()) + revert(); + return transfer(_to, _value); + } + + + function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { + if (isFueled + && now > closingTime + && !isBlocked(_from) + && _to != address(this) + && transferPaidOut(_from, _to, _value) + && super.transferFrom(_from, _to, _value)) { + + return true; + } else { + revert(); + } + } + + + function transferFromWithoutReward( + address payable _from, + address _to, + uint256 _value + ) public returns (bool success) { + + if (!withdrawRewardFor(_from)) + revert(); + return transferFrom(_from, _to, _value); + } + + + function transferPaidOut( + address _from, + address _to, + uint256 _value + ) internal returns (bool success) { + + uint transferPaidOut = paidOut[_from] * _value / balanceOf(_from); + if (transferPaidOut > paidOut[_from]) + revert(); + paidOut[_from] -= transferPaidOut; + paidOut[_to] += transferPaidOut; + return true; + } + + + function changeProposalDeposit(uint _proposalDeposit) external { + if (msg.sender != address(this) || _proposalDeposit > (actualBalance() + rewardToken[address(this)]) + / maxDepositDivisor) { + + revert(); + } + proposalDeposit = _proposalDeposit; + } + + + function changeAllowedRecipients(address _recipient, bool _allowed) external returns (bool _success) { + if (msg.sender != curator) + revert(); + allowedRecipients[_recipient] = _allowed; + emit AllowedRecipientChanged(_recipient, _allowed); + return true; + } + + + function isRecipientAllowed(address _recipient) internal returns (bool _isAllowed) { + if (allowedRecipients[_recipient] + || (_recipient == address(extraBalance) + // only allowed when at least the amount held in the + // extraBalance account has been spent from the DAO + && totalRewardToken > extraBalance.accumulatedInput())) + return true; + else + return false; + } + + function actualBalance() public view returns (uint _actualBalance) { + return address(this).balance - sumOfProposalDeposits; + } + + + function minQuorum(uint _value) internal view returns (uint _minQuorum) { + // minimum of 20% and maximum of 53.33% + return totalSupply / minQuorumDivisor + + (_value * totalSupply) / (3 * (actualBalance() + rewardToken[address(this)])); + } + + + function halveMinQuorum() public returns (bool _success) { + // this can only be called after `quorumHalvingPeriod` has passed or at anytime after + // fueling by the curator with a delay of at least `minProposalDebatePeriod` + // between the calls + if ((lastTimeMinQuorumMet < (now - quorumHalvingPeriod) || msg.sender == curator) + && lastTimeMinQuorumMet < (now - minProposalDebatePeriod) + && now >= closingTime + && proposals.length > 1) { + lastTimeMinQuorumMet = now; + minQuorumDivisor *= 2; + return true; + } else { + return false; + } + } + + function createNewDAO(address payable _newCurator) internal returns (DAO _newDAO) { + emit NewCurator(_newCurator); + return daoCreator.createDAO( + _newCurator, + 0, + 0, + now + splitExecutionPeriod, + name, + symbol, + decimals + ); + } + + function numberOfProposals() public view returns (uint _numberOfProposals) { + // Don't count index 0. It's used by isBlocked() and exists from start + return proposals.length - 1; + } + + function getNewDAOAddress(uint _proposalID) public view returns (address _newDAO) { + return address(proposals[_proposalID].splitData[0].newDAO); + } + + function isBlocked(address _account) internal returns (bool) { + if (blocked[_account] == 0) + return false; + Proposal storage p = proposals[blocked[_account]]; + if (now > p.votingDeadline) { + blocked[_account] = 0; + return false; + } else { + return true; + } + } + + function unblockMe() public returns (bool) { + return isBlocked(msg.sender); + } +} + +contract DAO_Creator { + function createDAO( + address payable _curator, + uint _proposalDeposit, + uint _minTokensToCreate, + uint _closingTime, + string memory _tokenName, + string memory _tokenSymbol, + uint8 _decimalPlaces + ) public returns (DAO _newDAO) { + + return new DAO( + _curator, + DAO_Creator(this), + _proposalDeposit, + _minTokensToCreate, + _closingTime, + msg.sender, + _tokenName, + _tokenSymbol, + _decimalPlaces + ); + } +} diff --git a/test/externalTests/solc-js/DAO/ManagedAccount.sol b/test/externalTests/solc-js/DAO/ManagedAccount.sol new file mode 100644 index 000000000000..5edb32696309 --- /dev/null +++ b/test/externalTests/solc-js/DAO/ManagedAccount.sol @@ -0,0 +1,68 @@ +/* +This file is part of the DAO. + +The DAO is free software: you can redistribute it and/or modify +it under the terms of the GNU lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The DAO 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 lesser General Public License for more details. + +You should have received a copy of the GNU lesser General Public License +along with the DAO. If not, see . +*/ + + +/* +Basic account, used by the DAO contract to separately manage both the rewards +and the extraBalance accounts. +*/ + +contract ManagedAccountInterface { + // The only address with permission to withdraw from this account + address public owner; + // If true, only the owner of the account can receive ether from it + bool public payOwnerOnly; + // The sum of ether (in wei) which has been sent to this contract + uint public accumulatedInput; + + /// @notice Sends `_amount` of wei to _recipient + /// @param _amount The amount of wei to send to `_recipient` + /// @param _recipient The address to receive `_amount` of wei + /// @return True if the send completed + function payOut(address payable _recipient, uint _amount) public returns (bool); + + event PayOut(address indexed _recipient, uint _amount); +} + + +contract ManagedAccount is ManagedAccountInterface{ + + // The constructor sets the owner of the account + constructor(address _owner, bool _payOwnerOnly) public { + owner = _owner; + payOwnerOnly = _payOwnerOnly; + } + + // When the contract receives a transaction without data this is called. + // It counts the amount of ether it receives and stores it in + // accumulatedInput. + function() external payable { + accumulatedInput += msg.value; + } + + function payOut(address payable _recipient, uint _amount) public returns (bool) { + if (msg.sender != owner || (payOwnerOnly && _recipient != owner)) + revert(); + (bool success,) = _recipient.call.value(_amount)(""); + if (success) { + emit PayOut(_recipient, _amount); + return true; + } else { + return false; + } + } +} diff --git a/test/externalTests/solc-js/DAO/Token.sol b/test/externalTests/solc-js/DAO/Token.sol new file mode 100644 index 000000000000..ee38f29d73b2 --- /dev/null +++ b/test/externalTests/solc-js/DAO/Token.sol @@ -0,0 +1,150 @@ +/* +This file is part of the DAO. + +The DAO is free software: you can redistribute it and/or modify +it under the terms of the GNU lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The DAO 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 lesser General Public License for more details. + +You should have received a copy of the GNU lesser General Public License +along with the DAO. If not, see . +*/ + + +/* +Basic, standardized Token contract with no "premine". Defines the functions to +check token balances, send tokens, send tokens on behalf of a 3rd party and the +corresponding approval process. Tokens need to be created by a derived +contract (e.g. TokenCreation.sol). + +Thank you ConsenSys, this contract originated from: +https://github.com/ConsenSys/Tokens/blob/master/Token_Contracts/contracts/Standard_Token.sol +Which is itself based on the Ethereum standardized contract APIs: +https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs +*/ + +/// @title Standard Token Contract. + +contract TokenInterface { + mapping (address => uint256) balances; + mapping (address => mapping (address => uint256)) allowed; + + /// Public variables of the token, all used for display + string public name; + string public symbol; + uint8 public decimals; + string public standard = 'Token 0.1'; + + /// Total amount of tokens + uint256 public totalSupply; + + /// @param _owner The address from which the balance will be retrieved + /// @return The balance + function balanceOf(address _owner) public view returns (uint256 balance); + + /// @notice Send `_amount` tokens to `_to` from `msg.sender` + /// @param _to The address of the recipient + /// @param _amount The amount of tokens to be transferred + /// @return Whether the transfer was successful or not + function transfer(address _to, uint256 _amount) public returns (bool success); + + /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it + /// is approved by `_from` + /// @param _from The address of the origin of the transfer + /// @param _to The address of the recipient + /// @param _amount The amount of tokens to be transferred + /// @return Whether the transfer was successful or not + function transferFrom(address _from, address _to, uint256 _amount) public returns (bool success); + + /// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on + /// its behalf + /// @param _spender The address of the account able to transfer the tokens + /// @param _amount The amount of tokens to be approved for transfer + /// @return Whether the approval was successful or not + function approve(address _spender, uint256 _amount) public returns (bool success); + + /// @param _owner The address of the account owning tokens + /// @param _spender The address of the account able to transfer the tokens + /// @return Amount of remaining tokens of _owner that _spender is allowed + /// to spend + function allowance( + address _owner, + address _spender + ) public view returns (uint256 remaining); + + event Transfer(address indexed _from, address indexed _to, uint256 _amount); + event Approval( + address indexed _owner, + address indexed _spender, + uint256 _amount + ); +} + +contract tokenRecipient { + function receiveApproval(address _from, uint256 _value, address _token, bytes memory _extraData) public; +} + +contract Token is TokenInterface { + // Protects users by preventing the execution of method calls that + // inadvertently also transferred ether + modifier noEther() {if (msg.value > 0) revert(); _; } + + function balanceOf(address _owner) public view returns (uint256 balance) { + return balances[_owner]; + } + + function transfer(address _to, uint256 _amount) public returns (bool success) { + if (balances[msg.sender] >= _amount && _amount > 0) { + balances[msg.sender] -= _amount; + balances[_to] += _amount; + emit Transfer(msg.sender, _to, _amount); + return true; + } else { + return false; + } + } + + function transferFrom( + address _from, + address _to, + uint256 _amount + ) public returns (bool success) { + + if (balances[_from] >= _amount + && allowed[_from][msg.sender] >= _amount + && _amount > 0) { + + balances[_to] += _amount; + balances[_from] -= _amount; + allowed[_from][msg.sender] -= _amount; + emit Transfer(_from, _to, _amount); + return true; + } else { + return false; + } + } + + function approve(address _spender, uint256 _amount) public returns (bool success) { + allowed[msg.sender][_spender] = _amount; + emit Approval(msg.sender, _spender, _amount); + return true; + } + + /// Allow another contract to spend some tokens in your behalf + function approveAndCall(address _spender, uint256 _value, bytes memory _extraData) + public returns (bool success) { + allowed[msg.sender][_spender] = _value; + tokenRecipient spender = tokenRecipient(_spender); + spender.receiveApproval(msg.sender, _value, address(this), _extraData); + return true; + } + + function allowance(address _owner, address _spender) public view returns (uint256 remaining) { + return allowed[_owner][_spender]; + } +} diff --git a/test/externalTests/solc-js/DAO/TokenCreation.sol b/test/externalTests/solc-js/DAO/TokenCreation.sol new file mode 100644 index 000000000000..1d22ebdf64bb --- /dev/null +++ b/test/externalTests/solc-js/DAO/TokenCreation.sol @@ -0,0 +1,155 @@ +/* +This file is part of the DAO. + +The DAO is free software: you can redistribute it and/or modify +it under the terms of the GNU lesser General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +The DAO 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 lesser General Public License for more details. + +You should have received a copy of the GNU lesser General Public License +along with the DAO. If not, see . +*/ + + +/* + * Token Creation contract, used by the DAO to create its tokens and initialize + * its ether. Feel free to modify the divisor method to implement different + * Token Creation parameters +*/ + +import "./Token.sol"; +import "./ManagedAccount.sol"; + +contract TokenCreationInterface { + + // End of token creation, in Unix time + uint public closingTime; + // Minimum fueling goal of the token creation, denominated in tokens to + // be created + uint public minTokensToCreate; + // True if the DAO reached its minimum fueling goal, false otherwise + bool public isFueled; + // For DAO splits - if privateCreation is 0, then it is a public token + // creation, otherwise only the address stored in privateCreation is + // allowed to create tokens + address public privateCreation; + // hold extra ether which has been sent after the DAO token + // creation rate has increased + ManagedAccount public extraBalance; + // tracks the amount of wei given from each contributor (used for refund) + mapping (address => uint256) weiGiven; + + /// @dev Constructor setting the minimum fueling goal and the + /// end of the Token Creation + /// @param _minTokensToCreate Minimum fueling goal in number of + /// Tokens to be created + /// @param _closingTime Date (in Unix time) of the end of the Token Creation + /// @param _privateCreation Zero means that the creation is public. A + /// non-zero address represents the only address that can create Tokens + /// (the address can also create Tokens on behalf of other accounts) + // This is the constructor: it can not be overloaded so it is commented out + // function TokenCreation( + // uint _minTokensTocreate, + // uint _closingTime, + // address _privateCreation + // string _tokenName, + // string _tokenSymbol, + // uint _decimalPlaces + // ); + + /// @notice Create Token with `_tokenHolder` as the initial owner of the Token + /// @param _tokenHolder The address of the Tokens's recipient + /// @return Whether the token creation was successful + function createTokenProxy(address payable _tokenHolder) payable public returns (bool success); + + /// @notice Refund `msg.sender` in the case the Token Creation did + /// not reach its minimum fueling goal + function refund() public; + + /// @return The divisor used to calculate the token creation rate during + /// the creation phase + function divisor() public view returns (uint divisor); + + event FuelingToDate(uint value); + event CreatedToken(address indexed to, uint amount); + event Refund(address indexed to, uint value); +} + + +contract TokenCreation is TokenCreationInterface, Token { + constructor( + uint _minTokensToCreate, + uint _closingTime, + address _privateCreation, + string memory _tokenName, + string memory _tokenSymbol, + uint8 _decimalPlaces) public { + + closingTime = _closingTime; + minTokensToCreate = _minTokensToCreate; + privateCreation = _privateCreation; + extraBalance = new ManagedAccount(address(this), true); + name = _tokenName; + symbol = _tokenSymbol; + decimals = _decimalPlaces; + + } + + function createTokenProxy(address payable _tokenHolder) payable public returns (bool success) { + if (now < closingTime && msg.value > 0 + && (privateCreation == 0x0000000000000000000000000000000000000000 || privateCreation == msg.sender)) { + + uint token = (msg.value * 20) / divisor(); + address(extraBalance).call.value(msg.value - token)(""); + balances[_tokenHolder] += token; + totalSupply += token; + weiGiven[_tokenHolder] += msg.value; + emit CreatedToken(_tokenHolder, token); + if (totalSupply >= minTokensToCreate && !isFueled) { + isFueled = true; + emit FuelingToDate(totalSupply); + } + return true; + } + revert(); + } + + function refund() public { + if (now > closingTime && !isFueled) { + // Get extraBalance - will only succeed when called for the first time + if (address(extraBalance).balance >= extraBalance.accumulatedInput()) + extraBalance.payOut(address(this), extraBalance.accumulatedInput()); + + // Execute refund + (bool success,) = msg.sender.call.value(weiGiven[msg.sender])(""); + if (success) { + emit Refund(msg.sender, weiGiven[msg.sender]); + totalSupply -= balances[msg.sender]; + balances[msg.sender] = 0; + weiGiven[msg.sender] = 0; + } + } + } + + function divisor() public view returns (uint divisor) { + // The number of (base unit) tokens per wei is calculated + // as `msg.value` * 20 / `divisor` + // The fueling period starts with a 1:1 ratio + if (closingTime - 2 weeks > now) { + return 20; + // Followed by 10 days with a daily creation rate increase of 5% + } else if (closingTime - 4 days > now) { + return (20 + (now - (closingTime - 2 weeks)) / (1 days)); + // The last 4 days there is a constant creation rate ratio of 1:1.5 + } else { + return 30; + } + } + function() external payable { + } +} diff --git a/test/externalTests/solc-js/determinism.js b/test/externalTests/solc-js/determinism.js new file mode 100644 index 000000000000..cd95d76ceb49 --- /dev/null +++ b/test/externalTests/solc-js/determinism.js @@ -0,0 +1,45 @@ +const tape = require('tape'); +const fs = require('fs'); +const solc = require('../index.js'); + +tape('Deterministic Compilation', function (t) { + t.test('DAO', function (st) { + var input = {}; + var prevBytecode = null; + var testdir = 'test/DAO/'; + var files = ['DAO.sol', 'Token.sol', 'TokenCreation.sol', 'ManagedAccount.sol']; + var i; + for (i in files) { + var file = files[i]; + input[file] = { content: fs.readFileSync(testdir + file, 'utf8') }; + } + for (i = 0; i < 10; i++) { + var output = JSON.parse(solc.compileStandardWrapper(JSON.stringify({ + language: 'Solidity', + settings: { + optimizer: { + enabled: true + }, + outputSelection: { + '*': { + '*': [ 'evm.bytecode' ] + } + } + }, + sources: input + }))); + st.ok(output); + st.ok(output.contracts); + st.ok(output.contracts['DAO.sol']); + st.ok(output.contracts['DAO.sol']['DAO']); + st.ok(output.contracts['DAO.sol']['DAO'].evm.bytecode.object); + var bytecode = output.contracts['DAO.sol']['DAO'].evm.bytecode.object; + st.ok(bytecode.length > 0); + if (prevBytecode !== null) { + st.equal(prevBytecode, bytecode); + } + prevBytecode = bytecode; + } + st.end(); + }); +}); diff --git a/test/solcjsTests.sh b/test/externalTests/solc-js/solc-js.sh similarity index 53% rename from test/solcjsTests.sh rename to test/externalTests/solc-js/solc-js.sh index 7c263d51f42a..4267ba11baf8 100755 --- a/test/solcjsTests.sh +++ b/test/externalTests/solc-js/solc-js.sh @@ -1,12 +1,5 @@ #!/usr/bin/env bash -#------------------------------------------------------------------------------ -# Bash script to execute the Solidity tests. -# -# The documentation for solidity is hosted at: -# -# https://solidity.readthedocs.org -# # ------------------------------------------------------------------------------ # This file is part of solidity. # @@ -23,41 +16,43 @@ # You should have received a copy of the GNU General Public License # along with solidity. If not, see # -# (c) 2017 solidity contributors. +# (c) 2019 solidity contributors. #------------------------------------------------------------------------------ +source scripts/common.sh +source test/externalTests/common.sh -set -e - -if [ ! -f "$1" -o -z "$2" ] -then - echo "Usage: $0 " - exit 1 -fi - +verify_version_input "$1" "$2" SOLJSON="$1" VERSION="$2" -DIR=$(mktemp -d) -( - echo "Preparing solc-js (master_060)..." - git clone --depth 1 --branch master_060 https://github.com/ethereum/solc-js "$DIR" - cd "$DIR" - # disable "prepublish" script which downloads the latest version - # (we will replace it anyway and it is often incorrectly cached - # on travis) - npm config set script.prepublish '' - npm install - - # Replace soljson with current build - echo "Replacing soljson.js" - rm -f soljson.js - cp "$SOLJSON" soljson.js +function install_fn { echo "Nothing to install."; } +function compile_fn { echo "Nothing to compile."; } +function test_fn { npm test; } + +function solcjs_test +{ + TEST_DIR=$(pwd) + SOLCJS_INPUT_DIR="$TEST_DIR"/test/externalTests/solc-js + + # set up solc-js on the branch specified + setup master_060 + + printLog "Updating index.js file..." + echo "require('./determinism.js');" >> test/index.js + + printLog "Copying determinism.js..." + cp -f $SOLCJS_INPUT_DIR/determinism.js test/ + + printLog "Copying contracts..." + cp -Rf $SOLCJS_INPUT_DIR/DAO test/ + + run_install install_fn # Update version (needed for some tests) echo "Updating package.json to version $VERSION" npm version --allow-same-version --no-git-tag-version $VERSION - echo "Running solc-js tests..." - npm run test -) -rm -rf "$DIR" + run_test compile_fn test_fn +} + +external_test solc-js solcjs_test diff --git a/test/externalTests/zeppelin.sh b/test/externalTests/zeppelin.sh index b24617f3704e..e18fef976582 100755 --- a/test/externalTests/zeppelin.sh +++ b/test/externalTests/zeppelin.sh @@ -31,13 +31,13 @@ function test_fn { npm run test; } function zeppelin_test { OPTIMIZER_LEVEL=1 - setup https://github.com/OpenZeppelin/openzeppelin-solidity.git master + truffle_setup https://github.com/OpenZeppelin/openzeppelin-solidity.git master run_install install_fn CONFIG="truffle-config.js" replace_libsolc_call - run_test compile_fn test_fn + truffle_run_test compile_fn test_fn } external_test Zeppelin zeppelin_test From e4f0414391cf9c45ce1f7ce97789b77a9c1b9f95 Mon Sep 17 00:00:00 2001 From: Erik Kundt Date: Wed, 25 Sep 2019 16:00:26 +0200 Subject: [PATCH 042/283] Updates solc-js test to 0.6.0. --- test/externalTests/solc-js/DAO/DAO.sol | 12 ++++++------ test/externalTests/solc-js/DAO/Token.sol | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/externalTests/solc-js/DAO/DAO.sol b/test/externalTests/solc-js/DAO/DAO.sol index 3aed551c6bcf..d9cefcd0e04b 100644 --- a/test/externalTests/solc-js/DAO/DAO.sol +++ b/test/externalTests/solc-js/DAO/DAO.sol @@ -295,7 +295,7 @@ contract DAOInterface { /// @notice Send `_amount` tokens to `_to` from `msg.sender`. Prior to this /// getMyReward() is called. /// @param _to The address of the recipient - /// @param _amount The amount of tokens to be transfered + /// @param _amount The amount of tokens to be transferred /// @return Whether the transfer was successful or not function transferWithoutReward(address _to, uint256 _amount) public returns (bool success); @@ -303,7 +303,7 @@ contract DAOInterface { /// is approved by `_from`. Prior to this getMyReward() is called. /// @param _from The address of the sender /// @param _to The address of the recipient - /// @param _amount The amount of tokens to be transfered + /// @param _amount The amount of tokens to be transferred /// @return Whether the transfer was successful or not function transferFromWithoutReward( address payable _from, @@ -383,7 +383,7 @@ contract DAO is DAOInterface, Token, TokenCreation { revert(); lastTimeMinQuorumMet = now; minQuorumDivisor = 5; // sets the minimal quorum to 20% - proposals.length = 1; // avoids a proposal with ID 0 because it is used + proposals.push(); // avoids a proposal with ID 0 because it is used allowedRecipients[address(this)] = true; allowedRecipients[curator] = true; @@ -447,8 +447,8 @@ contract DAO is DAOInterface, Token, TokenCreation { if (proposals.length == 1) // initial length is 1 (see constructor) lastTimeMinQuorumMet = now; - _proposalID = proposals.length++; - Proposal storage p = proposals[_proposalID]; + Proposal storage p = proposals.push(); + _proposalID = proposals.length - 1; p.recipient = _recipient; p.amount = _amount; p.description = _description; @@ -458,7 +458,7 @@ contract DAO is DAOInterface, Token, TokenCreation { //p.proposalPassed = False; // that's default p.newCurator = _newCurator; if (_newCurator) - p.splitData.length++; + p.splitData.push(); p.creator = msg.sender; p.proposalDeposit = msg.value; diff --git a/test/externalTests/solc-js/DAO/Token.sol b/test/externalTests/solc-js/DAO/Token.sol index ee38f29d73b2..77287b9b4970 100644 --- a/test/externalTests/solc-js/DAO/Token.sol +++ b/test/externalTests/solc-js/DAO/Token.sol @@ -34,7 +34,7 @@ contract TokenInterface { mapping (address => uint256) balances; mapping (address => mapping (address => uint256)) allowed; - /// Public variables of the token, all used for display + /// Public variables of the token, all used for display string public name; string public symbol; uint8 public decimals; @@ -85,7 +85,7 @@ contract TokenInterface { ); } -contract tokenRecipient { +contract tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes memory _extraData) public; } @@ -134,8 +134,8 @@ contract Token is TokenInterface { emit Approval(msg.sender, _spender, _amount); return true; } - - /// Allow another contract to spend some tokens in your behalf + + /// Allow another contract to spend some tokens in your behalf function approveAndCall(address _spender, uint256 _value, bytes memory _extraData) public returns (bool success) { allowed[msg.sender][_spender] = _value; From b40895c100c2332265dcb819792fcbe18211dd2a Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Thu, 26 Sep 2019 18:27:09 +0200 Subject: [PATCH 043/283] Fix try catch test --- .../syntaxTests/controlFlow/storageReturn/try_err.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/libsolidity/syntaxTests/controlFlow/storageReturn/try_err.sol b/test/libsolidity/syntaxTests/controlFlow/storageReturn/try_err.sol index ee9cb2f2a36b..6f6a889c8768 100644 --- a/test/libsolidity/syntaxTests/controlFlow/storageReturn/try_err.sol +++ b/test/libsolidity/syntaxTests/controlFlow/storageReturn/try_err.sol @@ -28,7 +28,7 @@ contract C { // ==== // EVMVersion: >=byzantium // ---- -// TypeError: (113-124): This variable is of storage pointer type and can be returned without prior assignment. -// TypeError: (240-251): This variable is of storage pointer type and can be returned without prior assignment. -// TypeError: (367-378): This variable is of storage pointer type and can be returned without prior assignment. -// TypeError: (631-632): This variable is of storage pointer type and can be accessed without prior assignment. +// TypeError: (113-124): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour. +// TypeError: (240-251): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour. +// TypeError: (367-378): This variable is of storage pointer type and can be returned without prior assignment, which would lead to undefined behaviour. +// TypeError: (631-632): This variable is of storage pointer type and can be accessed without prior assignment, which would lead to undefined behaviour. From 9d34d7de2fdae05134f9b6acc455236f640e2c4a Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Mon, 30 Sep 2019 02:32:28 +0300 Subject: [PATCH 044/283] Remove trailing spaces from JSON output --- libsolidity/ast/ASTJsonConverter.cpp | 3 +- scripts/check_style.sh | 2 +- .../recovery_ast_constructor/output | 476 +++++++++--------- 3 files changed, 241 insertions(+), 240 deletions(-) diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index 82d47b06c870..599656ebc90a 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -189,7 +190,7 @@ Json::Value ASTJsonConverter::inlineAssemblyIdentifierToJson(pair=", - "0.0", - ".0" - ] - }, - "id" : 1, - "name" : "PragmaDirective", - "src" : "0:24:0" - }, - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 18 - ], - "name" : "Error1", - "scope" : 19 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : true, - "kind" : "constructor", - "modifiers" : - [ - null - ], - "name" : "", - "overrides" : null, - "scope" : 18, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 2, - "name" : "ParameterList", - "src" : "57:2:0" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 3, - "name" : "ParameterList", - "src" : "67:0:0" - }, - { - "attributes" : - { - "statements" : - [ - null - ] - }, - "children" : [], - "id" : 8, - "name" : "Block", - "src" : "67:49:0" - } - ], - "id" : 9, - "name" : "FunctionDefinition", - "src" : "46:70:0" - }, - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "five", - "overrides" : null, - "scope" : 18, - "stateMutability" : "view", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 10, - "name" : "ParameterList", - "src" : "382:2:0" - }, - { - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "", - "overrides" : null, - "scope" : 17, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "uint256", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "name" : "uint", - "type" : "uint256" - }, - "id" : 11, - "name" : "ElementaryTypeName", - "src" : "405:4:0" - } - ], - "id" : 12, - "name" : "VariableDeclaration", - "src" : "405:4:0" - } - ], - "id" : 13, - "name" : "ParameterList", - "src" : "404:6:0" - }, - { - "children" : - [ - { - "attributes" : - { - "functionReturnParameters" : 13 - }, - "children" : - [ - { - "attributes" : - { - "argumentTypes" : null, - "hexvalue" : "35", - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "subdenomination" : null, - "token" : "number", - "type" : "int_const 5", - "value" : "5" - }, - "id" : 14, - "name" : "Literal", - "src" : "424:1:0" - } - ], - "id" : 15, - "name" : "Return", - "src" : "417:8:0" - } - ], - "id" : 16, - "name" : "Block", - "src" : "411:19:0" - } - ], - "id" : 17, - "name" : "FunctionDefinition", - "src" : "369:61:0" - } - ], - "id" : 18, - "name" : "ContractDefinition", - "src" : "26:406:0" - } - ], - "id" : 19, - "name" : "SourceUnit", - "src" : "0:433:0" + "attributes": + { + "absolutePath": "recovery_ast_constructor/input.sol", + "exportedSymbols": + { + "Error1": + [ + 18 + ] + } + }, + "children": + [ + { + "attributes": + { + "literals": + [ + "solidity", + ">=", + "0.0", + ".0" + ] + }, + "id": 1, + "name": "PragmaDirective", + "src": "0:24:0" + }, + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 18 + ], + "name": "Error1", + "scope": 19 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": true, + "kind": "constructor", + "modifiers": + [ + null + ], + "name": "", + "overrides": null, + "scope": 18, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 2, + "name": "ParameterList", + "src": "57:2:0" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 3, + "name": "ParameterList", + "src": "67:0:0" + }, + { + "attributes": + { + "statements": + [ + null + ] + }, + "children": [], + "id": 8, + "name": "Block", + "src": "67:49:0" + } + ], + "id": 9, + "name": "FunctionDefinition", + "src": "46:70:0" + }, + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "five", + "overrides": null, + "scope": 18, + "stateMutability": "view", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 10, + "name": "ParameterList", + "src": "382:2:0" + }, + { + "children": + [ + { + "attributes": + { + "constant": false, + "name": "", + "overrides": null, + "scope": 17, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 11, + "name": "ElementaryTypeName", + "src": "405:4:0" + } + ], + "id": 12, + "name": "VariableDeclaration", + "src": "405:4:0" + } + ], + "id": 13, + "name": "ParameterList", + "src": "404:6:0" + }, + { + "children": + [ + { + "attributes": + { + "functionReturnParameters": 13 + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "35", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 5", + "value": "5" + }, + "id": 14, + "name": "Literal", + "src": "424:1:0" + } + ], + "id": 15, + "name": "Return", + "src": "417:8:0" + } + ], + "id": 16, + "name": "Block", + "src": "411:19:0" + } + ], + "id": 17, + "name": "FunctionDefinition", + "src": "369:61:0" + } + ], + "id": 18, + "name": "ContractDefinition", + "src": "26:406:0" + } + ], + "id": 19, + "name": "SourceUnit", + "src": "0:433:0" } From 6c7e8494315060c157fc97dcc7a99bac16c33cf7 Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Wed, 2 Oct 2019 18:55:24 +0300 Subject: [PATCH 045/283] Modify the expectation files in ASTJSON tests The following changes to expecation files are required for the ASTJSON tests to pass: * remove trailing spaces in ASTJSON tests * replace indention tabs with 2 spaces in ASTJSON tests * remove the space between the key and the colon in ASTJSON tests --- test/libsolidity/ASTJSON/address_payable.json | 1132 +++++++-------- .../ASTJSON/address_payable_legacy.json | 1214 ++++++++--------- test/libsolidity/ASTJSON/array_type_name.json | 150 +- .../ASTJSON/array_type_name_legacy.json | 176 +-- test/libsolidity/ASTJSON/constructor.json | 138 +- .../ASTJSON/constructor_legacy.json | 218 +-- .../ASTJSON/contract_dep_order.json | 462 +++---- .../ASTJSON/contract_dep_order_legacy.json | 572 ++++---- test/libsolidity/ASTJSON/documentation.json | 350 ++--- .../ASTJSON/documentation_legacy.json | 352 ++--- test/libsolidity/ASTJSON/enum_value.json | 110 +- .../ASTJSON/enum_value_legacy.json | 152 +-- .../libsolidity/ASTJSON/event_definition.json | 96 +- .../ASTJSON/event_definition_legacy.json | 144 +- test/libsolidity/ASTJSON/fallback.json | 138 +- test/libsolidity/ASTJSON/fallback_legacy.json | 218 +-- .../libsolidity/ASTJSON/fallback_payable.json | 138 +- .../ASTJSON/fallback_payable_legacy.json | 218 +-- test/libsolidity/ASTJSON/function_type.json | 454 +++--- .../ASTJSON/function_type_legacy.json | 538 ++++---- test/libsolidity/ASTJSON/global_enum.json | 60 +- .../ASTJSON/global_enum_legacy.json | 78 +- test/libsolidity/ASTJSON/global_struct.json | 112 +- .../ASTJSON/global_struct_legacy.json | 124 +- .../ASTJSON/inheritance_specifier.json | 156 +-- .../ASTJSON/inheritance_specifier_legacy.json | 206 +-- .../long_type_name_binary_operation.json | 350 ++--- ...ong_type_name_binary_operation_legacy.json | 416 +++--- .../ASTJSON/long_type_name_identifier.json | 364 ++--- .../long_type_name_identifier_legacy.json | 442 +++--- .../ASTJSON/modifier_definition.json | 348 ++--- .../ASTJSON/modifier_definition_legacy.json | 424 +++--- .../ASTJSON/modifier_invocation.json | 348 ++--- .../ASTJSON/modifier_invocation_legacy.json | 424 +++--- test/libsolidity/ASTJSON/non_utf8.json | 244 ++-- test/libsolidity/ASTJSON/non_utf8_legacy.json | 312 ++--- test/libsolidity/ASTJSON/override.json | 670 ++++----- test/libsolidity/ASTJSON/override_legacy.json | 980 ++++++------- .../ASTJSON/placeholder_statement.json | 124 +- .../ASTJSON/placeholder_statement_legacy.json | 170 +-- test/libsolidity/ASTJSON/short_type_name.json | 252 ++-- .../ASTJSON/short_type_name_legacy.json | 326 ++--- .../ASTJSON/short_type_name_ref.json | 276 ++-- .../ASTJSON/short_type_name_ref_legacy.json | 352 ++--- test/libsolidity/ASTJSON/smoke.json | 62 +- test/libsolidity/ASTJSON/smoke_legacy.json | 92 +- test/libsolidity/ASTJSON/source_location.json | 320 ++--- .../ASTJSON/source_location_legacy.json | 398 +++--- .../ASTJSON/using_for_directive.json | 170 +-- .../ASTJSON/using_for_directive_legacy.json | 216 +-- 50 files changed, 7893 insertions(+), 7893 deletions(-) diff --git a/test/libsolidity/ASTJSON/address_payable.json b/test/libsolidity/ASTJSON/address_payable.json index 738d8371dbbd..2e7dda79c447 100644 --- a/test/libsolidity/ASTJSON/address_payable.json +++ b/test/libsolidity/ASTJSON/address_payable.json @@ -1,568 +1,568 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 39 - ] - }, - "id" : 40, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 39, - "linearizedBaseContracts" : - [ - 39 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "constant" : false, - "id" : 4, - "name" : "m", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 39, - "src" : "17:44:1", - "stateVariable" : true, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_mapping$_t_address_$_t_address_payable_$", - "typeString" : "mapping(address => address payable)" - }, - "typeName" : - { - "id" : 3, - "keyType" : - { - "id" : 1, - "name" : "address", - "nodeType" : "ElementaryTypeName", - "src" : "25:7:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_address", - "typeString" : "address" - } - }, - "nodeType" : "Mapping", - "src" : "17:35:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_mapping$_t_address_$_t_address_payable_$", - "typeString" : "mapping(address => address payable)" - }, - "valueType" : - { - "id" : 2, - "name" : "address", - "nodeType" : "ElementaryTypeName", - "src" : "36:15:1", - "stateMutability" : "payable", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - } - } - }, - "value" : null, - "visibility" : "public" - }, - { - "body" : - { - "id" : 37, - "nodeType" : "Block", - "src" : "134:122:1", - "statements" : - [ - { - "assignments" : - [ - 12 - ], - "declarations" : - [ - { - "constant" : false, - "id" : 12, - "name" : "a", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 37, - "src" : "144:17:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - }, - "typeName" : - { - "id" : 11, - "name" : "address", - "nodeType" : "ElementaryTypeName", - "src" : "144:15:1", - "stateMutability" : "payable", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "id" : 16, - "initialValue" : - { - "argumentTypes" : null, - "baseExpression" : - { - "argumentTypes" : null, - "id" : 13, - "name" : "m", - "nodeType" : "Identifier", - "overloadedDeclarations" : [], - "referencedDeclaration" : 4, - "src" : "164:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_mapping$_t_address_$_t_address_payable_$", - "typeString" : "mapping(address => address payable)" - } - }, - "id" : 15, - "indexExpression" : - { - "argumentTypes" : null, - "id" : 14, - "name" : "arg", - "nodeType" : "Identifier", - "overloadedDeclarations" : [], - "referencedDeclaration" : 6, - "src" : "166:3:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - } - }, - "isConstant" : false, - "isLValue" : true, - "isPure" : false, - "lValueRequested" : false, - "nodeType" : "IndexAccess", - "src" : "164:6:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - } - }, - "nodeType" : "VariableDeclarationStatement", - "src" : "144:26:1" - }, - { - "expression" : - { - "argumentTypes" : null, - "id" : 19, - "isConstant" : false, - "isLValue" : false, - "isPure" : false, - "lValueRequested" : false, - "leftHandSide" : - { - "argumentTypes" : null, - "id" : 17, - "name" : "r", - "nodeType" : "Identifier", - "overloadedDeclarations" : [], - "referencedDeclaration" : 9, - "src" : "180:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - } - }, - "nodeType" : "Assignment", - "operator" : "=", - "rightHandSide" : - { - "argumentTypes" : null, - "id" : 18, - "name" : "arg", - "nodeType" : "Identifier", - "overloadedDeclarations" : [], - "referencedDeclaration" : 6, - "src" : "184:3:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - } - }, - "src" : "180:7:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - } - }, - "id" : 20, - "nodeType" : "ExpressionStatement", - "src" : "180:7:1" - }, - { - "assignments" : - [ - 22 - ], - "declarations" : - [ - { - "constant" : false, - "id" : 22, - "name" : "c", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 37, - "src" : "197:9:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_address", - "typeString" : "address" - }, - "typeName" : - { - "id" : 21, - "name" : "address", - "nodeType" : "ElementaryTypeName", - "src" : "197:7:1", - "stateMutability" : "nonpayable", - "typeDescriptions" : - { - "typeIdentifier" : "t_address", - "typeString" : "address" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "id" : 27, - "initialValue" : - { - "argumentTypes" : null, - "arguments" : - [ - { - "argumentTypes" : null, - "id" : 25, - "name" : "this", - "nodeType" : "Identifier", - "overloadedDeclarations" : [], - "referencedDeclaration" : 68, - "src" : "217:4:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_contract$_C_$39", - "typeString" : "contract C" - } - } - ], - "expression" : - { - "argumentTypes" : - [ - { - "typeIdentifier" : "t_contract$_C_$39", - "typeString" : "contract C" - } - ], - "id" : 24, - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "nodeType" : "ElementaryTypeNameExpression", - "src" : "209:7:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_type$_t_address_$", - "typeString" : "type(address)" - }, - "typeName" : "address" - }, - "id" : 26, - "isConstant" : false, - "isLValue" : false, - "isPure" : false, - "kind" : "typeConversion", - "lValueRequested" : false, - "names" : [], - "nodeType" : "FunctionCall", - "src" : "209:13:1", - "tryCall" : false, - "typeDescriptions" : - { - "typeIdentifier" : "t_address", - "typeString" : "address" - } - }, - "nodeType" : "VariableDeclarationStatement", - "src" : "197:25:1" - }, - { - "expression" : - { - "argumentTypes" : null, - "id" : 35, - "isConstant" : false, - "isLValue" : false, - "isPure" : false, - "lValueRequested" : false, - "leftHandSide" : - { - "argumentTypes" : null, - "baseExpression" : - { - "argumentTypes" : null, - "id" : 28, - "name" : "m", - "nodeType" : "Identifier", - "overloadedDeclarations" : [], - "referencedDeclaration" : 4, - "src" : "232:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_mapping$_t_address_$_t_address_payable_$", - "typeString" : "mapping(address => address payable)" - } - }, - "id" : 30, - "indexExpression" : - { - "argumentTypes" : null, - "id" : 29, - "name" : "c", - "nodeType" : "Identifier", - "overloadedDeclarations" : [], - "referencedDeclaration" : 22, - "src" : "234:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_address", - "typeString" : "address" - } - }, - "isConstant" : false, - "isLValue" : true, - "isPure" : false, - "lValueRequested" : true, - "nodeType" : "IndexAccess", - "src" : "232:4:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - } - }, - "nodeType" : "Assignment", - "operator" : "=", - "rightHandSide" : - { - "argumentTypes" : null, - "arguments" : - [ - { - "argumentTypes" : null, - "hexValue" : "30", - "id" : 33, - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "kind" : "number", - "lValueRequested" : false, - "nodeType" : "Literal", - "src" : "247:1:1", - "subdenomination" : null, - "typeDescriptions" : - { - "typeIdentifier" : "t_rational_0_by_1", - "typeString" : "int_const 0" - }, - "value" : "0" - } - ], - "expression" : - { - "argumentTypes" : - [ - { - "typeIdentifier" : "t_rational_0_by_1", - "typeString" : "int_const 0" - } - ], - "id" : 32, - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "nodeType" : "ElementaryTypeNameExpression", - "src" : "239:7:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_type$_t_address_$", - "typeString" : "type(address)" - }, - "typeName" : "address" - }, - "id" : 34, - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "kind" : "typeConversion", - "lValueRequested" : false, - "names" : [], - "nodeType" : "FunctionCall", - "src" : "239:10:1", - "tryCall" : false, - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - } - }, - "src" : "232:17:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - } - }, - "id" : 36, - "nodeType" : "ExpressionStatement", - "src" : "232:17:1" - } - ] - }, - "documentation" : null, - "id" : 38, - "implemented" : true, - "kind" : "function", - "modifiers" : [], - "name" : "f", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 7, - "nodeType" : "ParameterList", - "parameters" : - [ - { - "constant" : false, - "id" : 6, - "name" : "arg", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 38, - "src" : "78:19:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - }, - "typeName" : - { - "id" : 5, - "name" : "address", - "nodeType" : "ElementaryTypeName", - "src" : "78:15:1", - "stateMutability" : "payable", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "src" : "77:21:1" - }, - "returnParameters" : - { - "id" : 10, - "nodeType" : "ParameterList", - "parameters" : - [ - { - "constant" : false, - "id" : 9, - "name" : "r", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 38, - "src" : "115:17:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - }, - "typeName" : - { - "id" : 8, - "name" : "address", - "nodeType" : "ElementaryTypeName", - "src" : "115:15:1", - "stateMutability" : "payable", - "typeDescriptions" : - { - "typeIdentifier" : "t_address_payable", - "typeString" : "address payable" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "src" : "114:19:1" - }, - "scope" : 39, - "src" : "67:189:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - } - ], - "scope" : 40, - "src" : "0:258:1" - } - ], - "src" : "0:259:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 39 + ] + }, + "id": 40, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 39, + "linearizedBaseContracts": + [ + 39 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "constant": false, + "id": 4, + "name": "m", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 39, + "src": "17:44:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_address_payable_$", + "typeString": "mapping(address => address payable)" + }, + "typeName": + { + "id": 3, + "keyType": + { + "id": 1, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "25:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "Mapping", + "src": "17:35:1", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_address_payable_$", + "typeString": "mapping(address => address payable)" + }, + "valueType": + { + "id": 2, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "36:15:1", + "stateMutability": "payable", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + } + }, + "value": null, + "visibility": "public" + }, + { + "body": + { + "id": 37, + "nodeType": "Block", + "src": "134:122:1", + "statements": + [ + { + "assignments": + [ + 12 + ], + "declarations": + [ + { + "constant": false, + "id": 12, + "name": "a", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 37, + "src": "144:17:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + }, + "typeName": + { + "id": 11, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "144:15:1", + "stateMutability": "payable", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 16, + "initialValue": + { + "argumentTypes": null, + "baseExpression": + { + "argumentTypes": null, + "id": 13, + "name": "m", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4, + "src": "164:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_address_payable_$", + "typeString": "mapping(address => address payable)" + } + }, + "id": 15, + "indexExpression": + { + "argumentTypes": null, + "id": 14, + "name": "arg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 6, + "src": "166:3:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "nodeType": "IndexAccess", + "src": "164:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "144:26:1" + }, + { + "expression": + { + "argumentTypes": null, + "id": 19, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "argumentTypes": null, + "id": 17, + "name": "r", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 9, + "src": "180:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "argumentTypes": null, + "id": 18, + "name": "arg", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 6, + "src": "184:3:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "src": "180:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "id": 20, + "nodeType": "ExpressionStatement", + "src": "180:7:1" + }, + { + "assignments": + [ + 22 + ], + "declarations": + [ + { + "constant": false, + "id": 22, + "name": "c", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 37, + "src": "197:9:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + }, + "typeName": + { + "id": 21, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "197:7:1", + "stateMutability": "nonpayable", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 27, + "initialValue": + { + "argumentTypes": null, + "arguments": + [ + { + "argumentTypes": null, + "id": 25, + "name": "this", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 68, + "src": "217:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_C_$39", + "typeString": "contract C" + } + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_C_$39", + "typeString": "contract C" + } + ], + "id": 24, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "209:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 26, + "isConstant": false, + "isLValue": false, + "isPure": false, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "209:13:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "197:25:1" + }, + { + "expression": + { + "argumentTypes": null, + "id": 35, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "leftHandSide": + { + "argumentTypes": null, + "baseExpression": + { + "argumentTypes": null, + "id": 28, + "name": "m", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 4, + "src": "232:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_mapping$_t_address_$_t_address_payable_$", + "typeString": "mapping(address => address payable)" + } + }, + "id": 30, + "indexExpression": + { + "argumentTypes": null, + "id": 29, + "name": "c", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 22, + "src": "234:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_address", + "typeString": "address" + } + }, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "nodeType": "IndexAccess", + "src": "232:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "nodeType": "Assignment", + "operator": "=", + "rightHandSide": + { + "argumentTypes": null, + "arguments": + [ + { + "argumentTypes": null, + "hexValue": "30", + "id": 33, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "247:1:1", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + }, + "value": "0" + } + ], + "expression": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "id": 32, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "nodeType": "ElementaryTypeNameExpression", + "src": "239:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_type$_t_address_$", + "typeString": "type(address)" + }, + "typeName": "address" + }, + "id": 34, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "typeConversion", + "lValueRequested": false, + "names": [], + "nodeType": "FunctionCall", + "src": "239:10:1", + "tryCall": false, + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "src": "232:17:1", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "id": 36, + "nodeType": "ExpressionStatement", + "src": "232:17:1" + } + ] + }, + "documentation": null, + "id": 38, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 7, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 6, + "name": "arg", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 38, + "src": "78:19:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + }, + "typeName": + { + "id": 5, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "78:15:1", + "stateMutability": "payable", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "77:21:1" + }, + "returnParameters": + { + "id": 10, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 9, + "name": "r", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 38, + "src": "115:17:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + }, + "typeName": + { + "id": 8, + "name": "address", + "nodeType": "ElementaryTypeName", + "src": "115:15:1", + "stateMutability": "payable", + "typeDescriptions": + { + "typeIdentifier": "t_address_payable", + "typeString": "address payable" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "114:19:1" + }, + "scope": 39, + "src": "67:189:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 40, + "src": "0:258:1" + } + ], + "src": "0:259:1" } diff --git a/test/libsolidity/ASTJSON/address_payable_legacy.json b/test/libsolidity/ASTJSON/address_payable_legacy.json index afcf195a5812..bbeac45421b0 100644 --- a/test/libsolidity/ASTJSON/address_payable_legacy.json +++ b/test/libsolidity/ASTJSON/address_payable_legacy.json @@ -1,609 +1,609 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 39 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 39 - ], - "name" : "C", - "scope" : 40 - }, - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "m", - "overrides" : null, - "scope" : 39, - "stateVariable" : true, - "storageLocation" : "default", - "type" : "mapping(address => address payable)", - "value" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "type" : "mapping(address => address payable)" - }, - "children" : - [ - { - "attributes" : - { - "name" : "address", - "type" : "address" - }, - "id" : 1, - "name" : "ElementaryTypeName", - "src" : "25:7:1" - }, - { - "attributes" : - { - "name" : "address", - "stateMutability" : "payable", - "type" : "address payable" - }, - "id" : 2, - "name" : "ElementaryTypeName", - "src" : "36:15:1" - } - ], - "id" : 3, - "name" : "Mapping", - "src" : "17:35:1" - } - ], - "id" : 4, - "name" : "VariableDeclaration", - "src" : "17:44:1" - }, - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "f", - "overrides" : null, - "scope" : 39, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "arg", - "overrides" : null, - "scope" : 38, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "address payable", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "name" : "address", - "stateMutability" : "payable", - "type" : "address payable" - }, - "id" : 5, - "name" : "ElementaryTypeName", - "src" : "78:15:1" - } - ], - "id" : 6, - "name" : "VariableDeclaration", - "src" : "78:19:1" - } - ], - "id" : 7, - "name" : "ParameterList", - "src" : "77:21:1" - }, - { - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "r", - "overrides" : null, - "scope" : 38, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "address payable", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "name" : "address", - "stateMutability" : "payable", - "type" : "address payable" - }, - "id" : 8, - "name" : "ElementaryTypeName", - "src" : "115:15:1" - } - ], - "id" : 9, - "name" : "VariableDeclaration", - "src" : "115:17:1" - } - ], - "id" : 10, - "name" : "ParameterList", - "src" : "114:19:1" - }, - { - "children" : - [ - { - "attributes" : - { - "assignments" : - [ - 12 - ] - }, - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "a", - "overrides" : null, - "scope" : 37, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "address payable", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "name" : "address", - "stateMutability" : "payable", - "type" : "address payable" - }, - "id" : 11, - "name" : "ElementaryTypeName", - "src" : "144:15:1" - } - ], - "id" : 12, - "name" : "VariableDeclaration", - "src" : "144:17:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "isConstant" : false, - "isLValue" : true, - "isPure" : false, - "lValueRequested" : false, - "type" : "address payable" - }, - "children" : - [ - { - "attributes" : - { - "argumentTypes" : null, - "overloadedDeclarations" : - [ - null - ], - "referencedDeclaration" : 4, - "type" : "mapping(address => address payable)", - "value" : "m" - }, - "id" : 13, - "name" : "Identifier", - "src" : "164:1:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "overloadedDeclarations" : - [ - null - ], - "referencedDeclaration" : 6, - "type" : "address payable", - "value" : "arg" - }, - "id" : 14, - "name" : "Identifier", - "src" : "166:3:1" - } - ], - "id" : 15, - "name" : "IndexAccess", - "src" : "164:6:1" - } - ], - "id" : 16, - "name" : "VariableDeclarationStatement", - "src" : "144:26:1" - }, - { - "children" : - [ - { - "attributes" : - { - "argumentTypes" : null, - "isConstant" : false, - "isLValue" : false, - "isPure" : false, - "lValueRequested" : false, - "operator" : "=", - "type" : "address payable" - }, - "children" : - [ - { - "attributes" : - { - "argumentTypes" : null, - "overloadedDeclarations" : - [ - null - ], - "referencedDeclaration" : 9, - "type" : "address payable", - "value" : "r" - }, - "id" : 17, - "name" : "Identifier", - "src" : "180:1:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "overloadedDeclarations" : - [ - null - ], - "referencedDeclaration" : 6, - "type" : "address payable", - "value" : "arg" - }, - "id" : 18, - "name" : "Identifier", - "src" : "184:3:1" - } - ], - "id" : 19, - "name" : "Assignment", - "src" : "180:7:1" - } - ], - "id" : 20, - "name" : "ExpressionStatement", - "src" : "180:7:1" - }, - { - "attributes" : - { - "assignments" : - [ - 22 - ] - }, - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "c", - "overrides" : null, - "scope" : 37, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "address", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "name" : "address", - "stateMutability" : "nonpayable", - "type" : "address" - }, - "id" : 21, - "name" : "ElementaryTypeName", - "src" : "197:7:1" - } - ], - "id" : 22, - "name" : "VariableDeclaration", - "src" : "197:9:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "isConstant" : false, - "isLValue" : false, - "isPure" : false, - "isStructConstructorCall" : false, - "lValueRequested" : false, - "names" : - [ - null - ], - "tryCall" : false, - "type" : "address", - "type_conversion" : true - }, - "children" : - [ - { - "attributes" : - { - "argumentTypes" : - [ - { - "typeIdentifier" : "t_contract$_C_$39", - "typeString" : "contract C" - } - ], - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "type" : "type(address)", - "value" : "address" - }, - "id" : 24, - "name" : "ElementaryTypeNameExpression", - "src" : "209:7:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "overloadedDeclarations" : - [ - null - ], - "referencedDeclaration" : 68, - "type" : "contract C", - "value" : "this" - }, - "id" : 25, - "name" : "Identifier", - "src" : "217:4:1" - } - ], - "id" : 26, - "name" : "FunctionCall", - "src" : "209:13:1" - } - ], - "id" : 27, - "name" : "VariableDeclarationStatement", - "src" : "197:25:1" - }, - { - "children" : - [ - { - "attributes" : - { - "argumentTypes" : null, - "isConstant" : false, - "isLValue" : false, - "isPure" : false, - "lValueRequested" : false, - "operator" : "=", - "type" : "address payable" - }, - "children" : - [ - { - "attributes" : - { - "argumentTypes" : null, - "isConstant" : false, - "isLValue" : true, - "isPure" : false, - "lValueRequested" : true, - "type" : "address payable" - }, - "children" : - [ - { - "attributes" : - { - "argumentTypes" : null, - "overloadedDeclarations" : - [ - null - ], - "referencedDeclaration" : 4, - "type" : "mapping(address => address payable)", - "value" : "m" - }, - "id" : 28, - "name" : "Identifier", - "src" : "232:1:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "overloadedDeclarations" : - [ - null - ], - "referencedDeclaration" : 22, - "type" : "address", - "value" : "c" - }, - "id" : 29, - "name" : "Identifier", - "src" : "234:1:1" - } - ], - "id" : 30, - "name" : "IndexAccess", - "src" : "232:4:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "isStructConstructorCall" : false, - "lValueRequested" : false, - "names" : - [ - null - ], - "tryCall" : false, - "type" : "address payable", - "type_conversion" : true - }, - "children" : - [ - { - "attributes" : - { - "argumentTypes" : - [ - { - "typeIdentifier" : "t_rational_0_by_1", - "typeString" : "int_const 0" - } - ], - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "type" : "type(address)", - "value" : "address" - }, - "id" : 32, - "name" : "ElementaryTypeNameExpression", - "src" : "239:7:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "hexvalue" : "30", - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "subdenomination" : null, - "token" : "number", - "type" : "int_const 0", - "value" : "0" - }, - "id" : 33, - "name" : "Literal", - "src" : "247:1:1" - } - ], - "id" : 34, - "name" : "FunctionCall", - "src" : "239:10:1" - } - ], - "id" : 35, - "name" : "Assignment", - "src" : "232:17:1" - } - ], - "id" : 36, - "name" : "ExpressionStatement", - "src" : "232:17:1" - } - ], - "id" : 37, - "name" : "Block", - "src" : "134:122:1" - } - ], - "id" : 38, - "name" : "FunctionDefinition", - "src" : "67:189:1" - } - ], - "id" : 39, - "name" : "ContractDefinition", - "src" : "0:258:1" - } - ], - "id" : 40, - "name" : "SourceUnit", - "src" : "0:259:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 39 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 39 + ], + "name": "C", + "scope": 40 + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "m", + "overrides": null, + "scope": 39, + "stateVariable": true, + "storageLocation": "default", + "type": "mapping(address => address payable)", + "value": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "type": "mapping(address => address payable)" + }, + "children": + [ + { + "attributes": + { + "name": "address", + "type": "address" + }, + "id": 1, + "name": "ElementaryTypeName", + "src": "25:7:1" + }, + { + "attributes": + { + "name": "address", + "stateMutability": "payable", + "type": "address payable" + }, + "id": 2, + "name": "ElementaryTypeName", + "src": "36:15:1" + } + ], + "id": 3, + "name": "Mapping", + "src": "17:35:1" + } + ], + "id": 4, + "name": "VariableDeclaration", + "src": "17:44:1" + }, + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "f", + "overrides": null, + "scope": 39, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "children": + [ + { + "attributes": + { + "constant": false, + "name": "arg", + "overrides": null, + "scope": 38, + "stateVariable": false, + "storageLocation": "default", + "type": "address payable", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "address", + "stateMutability": "payable", + "type": "address payable" + }, + "id": 5, + "name": "ElementaryTypeName", + "src": "78:15:1" + } + ], + "id": 6, + "name": "VariableDeclaration", + "src": "78:19:1" + } + ], + "id": 7, + "name": "ParameterList", + "src": "77:21:1" + }, + { + "children": + [ + { + "attributes": + { + "constant": false, + "name": "r", + "overrides": null, + "scope": 38, + "stateVariable": false, + "storageLocation": "default", + "type": "address payable", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "address", + "stateMutability": "payable", + "type": "address payable" + }, + "id": 8, + "name": "ElementaryTypeName", + "src": "115:15:1" + } + ], + "id": 9, + "name": "VariableDeclaration", + "src": "115:17:1" + } + ], + "id": 10, + "name": "ParameterList", + "src": "114:19:1" + }, + { + "children": + [ + { + "attributes": + { + "assignments": + [ + 12 + ] + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "a", + "overrides": null, + "scope": 37, + "stateVariable": false, + "storageLocation": "default", + "type": "address payable", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "address", + "stateMutability": "payable", + "type": "address payable" + }, + "id": 11, + "name": "ElementaryTypeName", + "src": "144:15:1" + } + ], + "id": 12, + "name": "VariableDeclaration", + "src": "144:17:1" + }, + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": false, + "type": "address payable" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 4, + "type": "mapping(address => address payable)", + "value": "m" + }, + "id": 13, + "name": "Identifier", + "src": "164:1:1" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 6, + "type": "address payable", + "value": "arg" + }, + "id": 14, + "name": "Identifier", + "src": "166:3:1" + } + ], + "id": 15, + "name": "IndexAccess", + "src": "164:6:1" + } + ], + "id": 16, + "name": "VariableDeclarationStatement", + "src": "144:26:1" + }, + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "address payable" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 9, + "type": "address payable", + "value": "r" + }, + "id": 17, + "name": "Identifier", + "src": "180:1:1" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 6, + "type": "address payable", + "value": "arg" + }, + "id": 18, + "name": "Identifier", + "src": "184:3:1" + } + ], + "id": 19, + "name": "Assignment", + "src": "180:7:1" + } + ], + "id": 20, + "name": "ExpressionStatement", + "src": "180:7:1" + }, + { + "attributes": + { + "assignments": + [ + 22 + ] + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "c", + "overrides": null, + "scope": 37, + "stateVariable": false, + "storageLocation": "default", + "type": "address", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "address", + "stateMutability": "nonpayable", + "type": "address" + }, + "id": 21, + "name": "ElementaryTypeName", + "src": "197:7:1" + } + ], + "id": 22, + "name": "VariableDeclaration", + "src": "197:9:1" + }, + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "tryCall": false, + "type": "address", + "type_conversion": true + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_contract$_C_$39", + "typeString": "contract C" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "type": "type(address)", + "value": "address" + }, + "id": 24, + "name": "ElementaryTypeNameExpression", + "src": "209:7:1" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 68, + "type": "contract C", + "value": "this" + }, + "id": 25, + "name": "Identifier", + "src": "217:4:1" + } + ], + "id": 26, + "name": "FunctionCall", + "src": "209:13:1" + } + ], + "id": 27, + "name": "VariableDeclarationStatement", + "src": "197:25:1" + }, + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "=", + "type": "address payable" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": true, + "isPure": false, + "lValueRequested": true, + "type": "address payable" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 4, + "type": "mapping(address => address payable)", + "value": "m" + }, + "id": 28, + "name": "Identifier", + "src": "232:1:1" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 22, + "type": "address", + "value": "c" + }, + "id": 29, + "name": "Identifier", + "src": "234:1:1" + } + ], + "id": 30, + "name": "IndexAccess", + "src": "232:4:1" + }, + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": true, + "isStructConstructorCall": false, + "lValueRequested": false, + "names": + [ + null + ], + "tryCall": false, + "type": "address payable", + "type_conversion": true + }, + "children": + [ + { + "attributes": + { + "argumentTypes": + [ + { + "typeIdentifier": "t_rational_0_by_1", + "typeString": "int_const 0" + } + ], + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "type": "type(address)", + "value": "address" + }, + "id": 32, + "name": "ElementaryTypeNameExpression", + "src": "239:7:1" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "30", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 0", + "value": "0" + }, + "id": 33, + "name": "Literal", + "src": "247:1:1" + } + ], + "id": 34, + "name": "FunctionCall", + "src": "239:10:1" + } + ], + "id": 35, + "name": "Assignment", + "src": "232:17:1" + } + ], + "id": 36, + "name": "ExpressionStatement", + "src": "232:17:1" + } + ], + "id": 37, + "name": "Block", + "src": "134:122:1" + } + ], + "id": 38, + "name": "FunctionDefinition", + "src": "67:189:1" + } + ], + "id": 39, + "name": "ContractDefinition", + "src": "0:258:1" + } + ], + "id": 40, + "name": "SourceUnit", + "src": "0:259:1" } diff --git a/test/libsolidity/ASTJSON/array_type_name.json b/test/libsolidity/ASTJSON/array_type_name.json index bc783ef88010..ba98b4b0b99d 100644 --- a/test/libsolidity/ASTJSON/array_type_name.json +++ b/test/libsolidity/ASTJSON/array_type_name.json @@ -1,77 +1,77 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 4 - ] - }, - "id" : 5, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 4, - "linearizedBaseContracts" : - [ - 4 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "constant" : false, - "id" : 3, - "name" : "i", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 4, - "src" : "13:8:1", - "stateVariable" : true, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_array$_t_uint256_$dyn_storage", - "typeString" : "uint256[]" - }, - "typeName" : - { - "baseType" : - { - "id" : 1, - "name" : "uint", - "nodeType" : "ElementaryTypeName", - "src" : "13:4:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - } - }, - "id" : 2, - "length" : null, - "nodeType" : "ArrayTypeName", - "src" : "13:6:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_array$_t_uint256_$dyn_storage_ptr", - "typeString" : "uint256[]" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "scope" : 5, - "src" : "0:24:1" - } - ], - "src" : "0:25:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 4 + ] + }, + "id": 5, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 4, + "linearizedBaseContracts": + [ + 4 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "constant": false, + "id": 3, + "name": "i", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 4, + "src": "13:8:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage", + "typeString": "uint256[]" + }, + "typeName": + { + "baseType": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "13:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2, + "length": null, + "nodeType": "ArrayTypeName", + "src": "13:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "scope": 5, + "src": "0:24:1" + } + ], + "src": "0:25:1" } diff --git a/test/libsolidity/ASTJSON/array_type_name_legacy.json b/test/libsolidity/ASTJSON/array_type_name_legacy.json index 749a49a69b25..3570098f4897 100644 --- a/test/libsolidity/ASTJSON/array_type_name_legacy.json +++ b/test/libsolidity/ASTJSON/array_type_name_legacy.json @@ -1,90 +1,90 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 4 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 4 - ], - "name" : "C", - "scope" : 5 - }, - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "i", - "overrides" : null, - "scope" : 4, - "stateVariable" : true, - "storageLocation" : "default", - "type" : "uint256[]", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "length" : null, - "type" : "uint256[]" - }, - "children" : - [ - { - "attributes" : - { - "name" : "uint", - "type" : "uint256" - }, - "id" : 1, - "name" : "ElementaryTypeName", - "src" : "13:4:1" - } - ], - "id" : 2, - "name" : "ArrayTypeName", - "src" : "13:6:1" - } - ], - "id" : 3, - "name" : "VariableDeclaration", - "src" : "13:8:1" - } - ], - "id" : 4, - "name" : "ContractDefinition", - "src" : "0:24:1" - } - ], - "id" : 5, - "name" : "SourceUnit", - "src" : "0:25:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 4 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 4 + ], + "name": "C", + "scope": 5 + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "i", + "overrides": null, + "scope": 4, + "stateVariable": true, + "storageLocation": "default", + "type": "uint256[]", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "length": null, + "type": "uint256[]" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 1, + "name": "ElementaryTypeName", + "src": "13:4:1" + } + ], + "id": 2, + "name": "ArrayTypeName", + "src": "13:6:1" + } + ], + "id": 3, + "name": "VariableDeclaration", + "src": "13:8:1" + } + ], + "id": 4, + "name": "ContractDefinition", + "src": "0:24:1" + } + ], + "id": 5, + "name": "SourceUnit", + "src": "0:25:1" } diff --git a/test/libsolidity/ASTJSON/constructor.json b/test/libsolidity/ASTJSON/constructor.json index d6a0d47ba92f..b12b8a6e8957 100644 --- a/test/libsolidity/ASTJSON/constructor.json +++ b/test/libsolidity/ASTJSON/constructor.json @@ -1,71 +1,71 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 5 - ] - }, - "id" : 6, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 5, - "linearizedBaseContracts" : - [ - 5 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 3, - "nodeType" : "Block", - "src" : "35:4:1", - "statements" : [] - }, - "documentation" : null, - "id" : 4, - "implemented" : true, - "kind" : "constructor", - "modifiers" : [], - "name" : "", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 1, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "25:2:1" - }, - "returnParameters" : - { - "id" : 2, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "35:0:1" - }, - "scope" : 5, - "src" : "14:25:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - } - ], - "scope" : 6, - "src" : "0:41:1" - } - ], - "src" : "0:42:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + }, + "id": 6, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "35:4:1", + "statements": [] + }, + "documentation": null, + "id": 4, + "implemented": true, + "kind": "constructor", + "modifiers": [], + "name": "", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "25:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "35:0:1" + }, + "scope": 5, + "src": "14:25:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 6, + "src": "0:41:1" + } + ], + "src": "0:42:1" } diff --git a/test/libsolidity/ASTJSON/constructor_legacy.json b/test/libsolidity/ASTJSON/constructor_legacy.json index c5e1d3a142b4..874d11fff38b 100644 --- a/test/libsolidity/ASTJSON/constructor_legacy.json +++ b/test/libsolidity/ASTJSON/constructor_legacy.json @@ -1,111 +1,111 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 5 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 5 - ], - "name" : "C", - "scope" : 6 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : true, - "kind" : "constructor", - "modifiers" : - [ - null - ], - "name" : "", - "overrides" : null, - "scope" : 5, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 1, - "name" : "ParameterList", - "src" : "25:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 2, - "name" : "ParameterList", - "src" : "35:0:1" - }, - { - "attributes" : - { - "statements" : - [ - null - ] - }, - "children" : [], - "id" : 3, - "name" : "Block", - "src" : "35:4:1" - } - ], - "id" : 4, - "name" : "FunctionDefinition", - "src" : "14:25:1" - } - ], - "id" : 5, - "name" : "ContractDefinition", - "src" : "0:41:1" - } - ], - "id" : 6, - "name" : "SourceUnit", - "src" : "0:42:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "scope": 6 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": true, + "kind": "constructor", + "modifiers": + [ + null + ], + "name": "", + "overrides": null, + "scope": 5, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 1, + "name": "ParameterList", + "src": "25:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 2, + "name": "ParameterList", + "src": "35:0:1" + }, + { + "attributes": + { + "statements": + [ + null + ] + }, + "children": [], + "id": 3, + "name": "Block", + "src": "35:4:1" + } + ], + "id": 4, + "name": "FunctionDefinition", + "src": "14:25:1" + } + ], + "id": 5, + "name": "ContractDefinition", + "src": "0:41:1" + } + ], + "id": 6, + "name": "SourceUnit", + "src": "0:42:1" } diff --git a/test/libsolidity/ASTJSON/contract_dep_order.json b/test/libsolidity/ASTJSON/contract_dep_order.json index de42ca600590..521ad93f1643 100644 --- a/test/libsolidity/ASTJSON/contract_dep_order.json +++ b/test/libsolidity/ASTJSON/contract_dep_order.json @@ -1,233 +1,233 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "A" : - [ - 1 - ], - "B" : - [ - 4 - ], - "C" : - [ - 7 - ], - "D" : - [ - 10 - ], - "E" : - [ - 13 - ] - }, - "id" : 14, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 1, - "linearizedBaseContracts" : - [ - 1 - ], - "name" : "A", - "nodeType" : "ContractDefinition", - "nodes" : [], - "scope" : 14, - "src" : "0:14:1" - }, - { - "baseContracts" : - [ - { - "arguments" : null, - "baseName" : - { - "contractScope" : null, - "id" : 2, - "name" : "A", - "nodeType" : "UserDefinedTypeName", - "referencedDeclaration" : 1, - "src" : "29:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_contract$_A_$1", - "typeString" : "contract A" - } - }, - "id" : 3, - "nodeType" : "InheritanceSpecifier", - "src" : "29:1:1" - } - ], - "contractDependencies" : - [ - 1 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 4, - "linearizedBaseContracts" : - [ - 4, - 1 - ], - "name" : "B", - "nodeType" : "ContractDefinition", - "nodes" : [], - "scope" : 14, - "src" : "15:19:1" - }, - { - "baseContracts" : - [ - { - "arguments" : null, - "baseName" : - { - "contractScope" : null, - "id" : 5, - "name" : "B", - "nodeType" : "UserDefinedTypeName", - "referencedDeclaration" : 4, - "src" : "49:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_contract$_B_$4", - "typeString" : "contract B" - } - }, - "id" : 6, - "nodeType" : "InheritanceSpecifier", - "src" : "49:1:1" - } - ], - "contractDependencies" : - [ - 1, - 4 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 7, - "linearizedBaseContracts" : - [ - 7, - 4, - 1 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : [], - "scope" : 14, - "src" : "35:19:1" - }, - { - "baseContracts" : - [ - { - "arguments" : null, - "baseName" : - { - "contractScope" : null, - "id" : 8, - "name" : "C", - "nodeType" : "UserDefinedTypeName", - "referencedDeclaration" : 7, - "src" : "69:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_contract$_C_$7", - "typeString" : "contract C" - } - }, - "id" : 9, - "nodeType" : "InheritanceSpecifier", - "src" : "69:1:1" - } - ], - "contractDependencies" : - [ - 1, - 4, - 7 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 10, - "linearizedBaseContracts" : - [ - 10, - 7, - 4, - 1 - ], - "name" : "D", - "nodeType" : "ContractDefinition", - "nodes" : [], - "scope" : 14, - "src" : "55:19:1" - }, - { - "baseContracts" : - [ - { - "arguments" : null, - "baseName" : - { - "contractScope" : null, - "id" : 11, - "name" : "D", - "nodeType" : "UserDefinedTypeName", - "referencedDeclaration" : 10, - "src" : "89:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_contract$_D_$10", - "typeString" : "contract D" - } - }, - "id" : 12, - "nodeType" : "InheritanceSpecifier", - "src" : "89:1:1" - } - ], - "contractDependencies" : - [ - 1, - 4, - 7, - 10 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 13, - "linearizedBaseContracts" : - [ - 13, - 10, - 7, - 4, - 1 - ], - "name" : "E", - "nodeType" : "ContractDefinition", - "nodes" : [], - "scope" : 14, - "src" : "75:19:1" - } - ], - "src" : "0:95:1" + "absolutePath": "a", + "exportedSymbols": + { + "A": + [ + 1 + ], + "B": + [ + 4 + ], + "C": + [ + 7 + ], + "D": + [ + 10 + ], + "E": + [ + 13 + ] + }, + "id": 14, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 1, + "linearizedBaseContracts": + [ + 1 + ], + "name": "A", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 14, + "src": "0:14:1" + }, + { + "baseContracts": + [ + { + "arguments": null, + "baseName": + { + "contractScope": null, + "id": 2, + "name": "A", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 1, + "src": "29:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_A_$1", + "typeString": "contract A" + } + }, + "id": 3, + "nodeType": "InheritanceSpecifier", + "src": "29:1:1" + } + ], + "contractDependencies": + [ + 1 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 4, + "linearizedBaseContracts": + [ + 4, + 1 + ], + "name": "B", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 14, + "src": "15:19:1" + }, + { + "baseContracts": + [ + { + "arguments": null, + "baseName": + { + "contractScope": null, + "id": 5, + "name": "B", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 4, + "src": "49:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_B_$4", + "typeString": "contract B" + } + }, + "id": 6, + "nodeType": "InheritanceSpecifier", + "src": "49:1:1" + } + ], + "contractDependencies": + [ + 1, + 4 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 7, + "linearizedBaseContracts": + [ + 7, + 4, + 1 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 14, + "src": "35:19:1" + }, + { + "baseContracts": + [ + { + "arguments": null, + "baseName": + { + "contractScope": null, + "id": 8, + "name": "C", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 7, + "src": "69:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_C_$7", + "typeString": "contract C" + } + }, + "id": 9, + "nodeType": "InheritanceSpecifier", + "src": "69:1:1" + } + ], + "contractDependencies": + [ + 1, + 4, + 7 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 10, + "linearizedBaseContracts": + [ + 10, + 7, + 4, + 1 + ], + "name": "D", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 14, + "src": "55:19:1" + }, + { + "baseContracts": + [ + { + "arguments": null, + "baseName": + { + "contractScope": null, + "id": 11, + "name": "D", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 10, + "src": "89:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_D_$10", + "typeString": "contract D" + } + }, + "id": 12, + "nodeType": "InheritanceSpecifier", + "src": "89:1:1" + } + ], + "contractDependencies": + [ + 1, + 4, + 7, + 10 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 13, + "linearizedBaseContracts": + [ + 13, + 10, + 7, + 4, + 1 + ], + "name": "E", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 14, + "src": "75:19:1" + } + ], + "src": "0:95:1" } diff --git a/test/libsolidity/ASTJSON/contract_dep_order_legacy.json b/test/libsolidity/ASTJSON/contract_dep_order_legacy.json index 5990b52caf52..ff80f7fb6ec1 100644 --- a/test/libsolidity/ASTJSON/contract_dep_order_legacy.json +++ b/test/libsolidity/ASTJSON/contract_dep_order_legacy.json @@ -1,288 +1,288 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "A" : - [ - 1 - ], - "B" : - [ - 4 - ], - "C" : - [ - 7 - ], - "D" : - [ - 10 - ], - "E" : - [ - 13 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 1 - ], - "name" : "A", - "nodes" : - [ - null - ], - "scope" : 14 - }, - "id" : 1, - "name" : "ContractDefinition", - "src" : "0:14:1" - }, - { - "attributes" : - { - "contractDependencies" : - [ - 1 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 4, - 1 - ], - "name" : "B", - "nodes" : - [ - null - ], - "scope" : 14 - }, - "children" : - [ - { - "attributes" : - { - "arguments" : null - }, - "children" : - [ - { - "attributes" : - { - "contractScope" : null, - "name" : "A", - "referencedDeclaration" : 1, - "type" : "contract A" - }, - "id" : 2, - "name" : "UserDefinedTypeName", - "src" : "29:1:1" - } - ], - "id" : 3, - "name" : "InheritanceSpecifier", - "src" : "29:1:1" - } - ], - "id" : 4, - "name" : "ContractDefinition", - "src" : "15:19:1" - }, - { - "attributes" : - { - "contractDependencies" : - [ - 1, - 4 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 7, - 4, - 1 - ], - "name" : "C", - "nodes" : - [ - null - ], - "scope" : 14 - }, - "children" : - [ - { - "attributes" : - { - "arguments" : null - }, - "children" : - [ - { - "attributes" : - { - "contractScope" : null, - "name" : "B", - "referencedDeclaration" : 4, - "type" : "contract B" - }, - "id" : 5, - "name" : "UserDefinedTypeName", - "src" : "49:1:1" - } - ], - "id" : 6, - "name" : "InheritanceSpecifier", - "src" : "49:1:1" - } - ], - "id" : 7, - "name" : "ContractDefinition", - "src" : "35:19:1" - }, - { - "attributes" : - { - "contractDependencies" : - [ - 1, - 4, - 7 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 10, - 7, - 4, - 1 - ], - "name" : "D", - "nodes" : - [ - null - ], - "scope" : 14 - }, - "children" : - [ - { - "attributes" : - { - "arguments" : null - }, - "children" : - [ - { - "attributes" : - { - "contractScope" : null, - "name" : "C", - "referencedDeclaration" : 7, - "type" : "contract C" - }, - "id" : 8, - "name" : "UserDefinedTypeName", - "src" : "69:1:1" - } - ], - "id" : 9, - "name" : "InheritanceSpecifier", - "src" : "69:1:1" - } - ], - "id" : 10, - "name" : "ContractDefinition", - "src" : "55:19:1" - }, - { - "attributes" : - { - "contractDependencies" : - [ - 1, - 4, - 7, - 10 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 13, - 10, - 7, - 4, - 1 - ], - "name" : "E", - "nodes" : - [ - null - ], - "scope" : 14 - }, - "children" : - [ - { - "attributes" : - { - "arguments" : null - }, - "children" : - [ - { - "attributes" : - { - "contractScope" : null, - "name" : "D", - "referencedDeclaration" : 10, - "type" : "contract D" - }, - "id" : 11, - "name" : "UserDefinedTypeName", - "src" : "89:1:1" - } - ], - "id" : 12, - "name" : "InheritanceSpecifier", - "src" : "89:1:1" - } - ], - "id" : 13, - "name" : "ContractDefinition", - "src" : "75:19:1" - } - ], - "id" : 14, - "name" : "SourceUnit", - "src" : "0:95:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "A": + [ + 1 + ], + "B": + [ + 4 + ], + "C": + [ + 7 + ], + "D": + [ + 10 + ], + "E": + [ + 13 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 1 + ], + "name": "A", + "nodes": + [ + null + ], + "scope": 14 + }, + "id": 1, + "name": "ContractDefinition", + "src": "0:14:1" + }, + { + "attributes": + { + "contractDependencies": + [ + 1 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 4, + 1 + ], + "name": "B", + "nodes": + [ + null + ], + "scope": 14 + }, + "children": + [ + { + "attributes": + { + "arguments": null + }, + "children": + [ + { + "attributes": + { + "contractScope": null, + "name": "A", + "referencedDeclaration": 1, + "type": "contract A" + }, + "id": 2, + "name": "UserDefinedTypeName", + "src": "29:1:1" + } + ], + "id": 3, + "name": "InheritanceSpecifier", + "src": "29:1:1" + } + ], + "id": 4, + "name": "ContractDefinition", + "src": "15:19:1" + }, + { + "attributes": + { + "contractDependencies": + [ + 1, + 4 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 7, + 4, + 1 + ], + "name": "C", + "nodes": + [ + null + ], + "scope": 14 + }, + "children": + [ + { + "attributes": + { + "arguments": null + }, + "children": + [ + { + "attributes": + { + "contractScope": null, + "name": "B", + "referencedDeclaration": 4, + "type": "contract B" + }, + "id": 5, + "name": "UserDefinedTypeName", + "src": "49:1:1" + } + ], + "id": 6, + "name": "InheritanceSpecifier", + "src": "49:1:1" + } + ], + "id": 7, + "name": "ContractDefinition", + "src": "35:19:1" + }, + { + "attributes": + { + "contractDependencies": + [ + 1, + 4, + 7 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 10, + 7, + 4, + 1 + ], + "name": "D", + "nodes": + [ + null + ], + "scope": 14 + }, + "children": + [ + { + "attributes": + { + "arguments": null + }, + "children": + [ + { + "attributes": + { + "contractScope": null, + "name": "C", + "referencedDeclaration": 7, + "type": "contract C" + }, + "id": 8, + "name": "UserDefinedTypeName", + "src": "69:1:1" + } + ], + "id": 9, + "name": "InheritanceSpecifier", + "src": "69:1:1" + } + ], + "id": 10, + "name": "ContractDefinition", + "src": "55:19:1" + }, + { + "attributes": + { + "contractDependencies": + [ + 1, + 4, + 7, + 10 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 13, + 10, + 7, + 4, + 1 + ], + "name": "E", + "nodes": + [ + null + ], + "scope": 14 + }, + "children": + [ + { + "attributes": + { + "arguments": null + }, + "children": + [ + { + "attributes": + { + "contractScope": null, + "name": "D", + "referencedDeclaration": 10, + "type": "contract D" + }, + "id": 11, + "name": "UserDefinedTypeName", + "src": "89:1:1" + } + ], + "id": 12, + "name": "InheritanceSpecifier", + "src": "89:1:1" + } + ], + "id": 13, + "name": "ContractDefinition", + "src": "75:19:1" + } + ], + "id": 14, + "name": "SourceUnit", + "src": "0:95:1" } diff --git a/test/libsolidity/ASTJSON/documentation.json b/test/libsolidity/ASTJSON/documentation.json index a761c836c84c..455ac099ed68 100644 --- a/test/libsolidity/ASTJSON/documentation.json +++ b/test/libsolidity/ASTJSON/documentation.json @@ -1,181 +1,181 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 1 - ] - }, - "id" : 2, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : "This contract is empty", - "fullyImplemented" : true, - "id" : 1, - "linearizedBaseContracts" : - [ - 1 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : [], - "scope" : 2, - "src" : "28:13:1" - } - ], - "src" : "28:14:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 1 + ] + }, + "id": 2, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": "This contract is empty", + "fullyImplemented": true, + "id": 1, + "linearizedBaseContracts": + [ + 1 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 2, + "src": "28:13:1" + } + ], + "src": "28:14:1" }, { - "absolutePath" : "b", - "exportedSymbols" : - { - "C" : - [ - 3 - ] - }, - "id" : 4, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : "This contract is empty\nand has a line-breaking comment.", - "fullyImplemented" : true, - "id" : 3, - "linearizedBaseContracts" : - [ - 3 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : [], - "scope" : 4, - "src" : "62:13:2" - } - ], - "src" : "62:14:2" + "absolutePath": "b", + "exportedSymbols": + { + "C": + [ + 3 + ] + }, + "id": 4, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": "This contract is empty\nand has a line-breaking comment.", + "fullyImplemented": true, + "id": 3, + "linearizedBaseContracts": + [ + 3 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 4, + "src": "62:13:2" + } + ], + "src": "62:14:2" }, { - "absolutePath" : "c", - "exportedSymbols" : - { - "C" : - [ - 15 - ] - }, - "id" : 16, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 15, - "linearizedBaseContracts" : - [ - 15 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "anonymous" : false, - "documentation" : "Some comment on Evt.", - "id" : 6, - "name" : "Evt", - "nodeType" : "EventDefinition", - "parameters" : - { - "id" : 5, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "51:2:3" - }, - "src" : "42:12:3" - }, - { - "body" : - { - "id" : 9, - "nodeType" : "Block", - "src" : "99:6:3", - "statements" : - [ - { - "id" : 8, - "nodeType" : "PlaceholderStatement", - "src" : "101:1:3" - } - ] - }, - "documentation" : "Some comment on mod.", - "id" : 10, - "name" : "mod", - "nodeType" : "ModifierDefinition", - "parameters" : - { - "id" : 7, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "96:2:3" - }, - "src" : "84:21:3", - "visibility" : "internal" - }, - { - "body" : - { - "id" : 13, - "nodeType" : "Block", - "src" : "155:2:3", - "statements" : [] - }, - "documentation" : "Some comment on fn.", - "id" : 14, - "implemented" : true, - "kind" : "function", - "modifiers" : [], - "name" : "fn", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 11, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "145:2:3" - }, - "returnParameters" : - { - "id" : 12, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "155:0:3" - }, - "scope" : 15, - "src" : "134:23:3", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - } - ], - "scope" : 16, - "src" : "0:159:3" - } - ], - "src" : "0:160:3" + "absolutePath": "c", + "exportedSymbols": + { + "C": + [ + 15 + ] + }, + "id": 16, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 15, + "linearizedBaseContracts": + [ + 15 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "anonymous": false, + "documentation": "Some comment on Evt.", + "id": 6, + "name": "Evt", + "nodeType": "EventDefinition", + "parameters": + { + "id": 5, + "nodeType": "ParameterList", + "parameters": [], + "src": "51:2:3" + }, + "src": "42:12:3" + }, + { + "body": + { + "id": 9, + "nodeType": "Block", + "src": "99:6:3", + "statements": + [ + { + "id": 8, + "nodeType": "PlaceholderStatement", + "src": "101:1:3" + } + ] + }, + "documentation": "Some comment on mod.", + "id": 10, + "name": "mod", + "nodeType": "ModifierDefinition", + "parameters": + { + "id": 7, + "nodeType": "ParameterList", + "parameters": [], + "src": "96:2:3" + }, + "src": "84:21:3", + "visibility": "internal" + }, + { + "body": + { + "id": 13, + "nodeType": "Block", + "src": "155:2:3", + "statements": [] + }, + "documentation": "Some comment on fn.", + "id": 14, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "fn", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 11, + "nodeType": "ParameterList", + "parameters": [], + "src": "145:2:3" + }, + "returnParameters": + { + "id": 12, + "nodeType": "ParameterList", + "parameters": [], + "src": "155:0:3" + }, + "scope": 15, + "src": "134:23:3", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 16, + "src": "0:159:3" + } + ], + "src": "0:160:3" } diff --git a/test/libsolidity/ASTJSON/documentation_legacy.json b/test/libsolidity/ASTJSON/documentation_legacy.json index 1dc3d9a4a359..ac077b88a0cd 100644 --- a/test/libsolidity/ASTJSON/documentation_legacy.json +++ b/test/libsolidity/ASTJSON/documentation_legacy.json @@ -1,178 +1,178 @@ { - "attributes" : - { - "absolutePath" : "c", - "exportedSymbols" : - { - "C" : - [ - 15 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 15 - ], - "name" : "C", - "scope" : 16 - }, - "children" : - [ - { - "attributes" : - { - "anonymous" : false, - "documentation" : "Some comment on Evt.", - "name" : "Evt" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 5, - "name" : "ParameterList", - "src" : "51:2:3" - } - ], - "id" : 6, - "name" : "EventDefinition", - "src" : "42:12:3" - }, - { - "attributes" : - { - "documentation" : "Some comment on mod.", - "name" : "mod", - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 7, - "name" : "ParameterList", - "src" : "96:2:3" - }, - { - "children" : - [ - { - "id" : 8, - "name" : "PlaceholderStatement", - "src" : "101:1:3" - } - ], - "id" : 9, - "name" : "Block", - "src" : "99:6:3" - } - ], - "id" : 10, - "name" : "ModifierDefinition", - "src" : "84:21:3" - }, - { - "attributes" : - { - "documentation" : "Some comment on fn.", - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "fn", - "overrides" : null, - "scope" : 15, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 11, - "name" : "ParameterList", - "src" : "145:2:3" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 12, - "name" : "ParameterList", - "src" : "155:0:3" - }, - { - "attributes" : - { - "statements" : - [ - null - ] - }, - "children" : [], - "id" : 13, - "name" : "Block", - "src" : "155:2:3" - } - ], - "id" : 14, - "name" : "FunctionDefinition", - "src" : "134:23:3" - } - ], - "id" : 15, - "name" : "ContractDefinition", - "src" : "0:159:3" - } - ], - "id" : 16, - "name" : "SourceUnit", - "src" : "0:160:3" + "attributes": + { + "absolutePath": "c", + "exportedSymbols": + { + "C": + [ + 15 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 15 + ], + "name": "C", + "scope": 16 + }, + "children": + [ + { + "attributes": + { + "anonymous": false, + "documentation": "Some comment on Evt.", + "name": "Evt" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 5, + "name": "ParameterList", + "src": "51:2:3" + } + ], + "id": 6, + "name": "EventDefinition", + "src": "42:12:3" + }, + { + "attributes": + { + "documentation": "Some comment on mod.", + "name": "mod", + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 7, + "name": "ParameterList", + "src": "96:2:3" + }, + { + "children": + [ + { + "id": 8, + "name": "PlaceholderStatement", + "src": "101:1:3" + } + ], + "id": 9, + "name": "Block", + "src": "99:6:3" + } + ], + "id": 10, + "name": "ModifierDefinition", + "src": "84:21:3" + }, + { + "attributes": + { + "documentation": "Some comment on fn.", + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "fn", + "overrides": null, + "scope": 15, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 11, + "name": "ParameterList", + "src": "145:2:3" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 12, + "name": "ParameterList", + "src": "155:0:3" + }, + { + "attributes": + { + "statements": + [ + null + ] + }, + "children": [], + "id": 13, + "name": "Block", + "src": "155:2:3" + } + ], + "id": 14, + "name": "FunctionDefinition", + "src": "134:23:3" + } + ], + "id": 15, + "name": "ContractDefinition", + "src": "0:159:3" + } + ], + "id": 16, + "name": "SourceUnit", + "src": "0:160:3" } diff --git a/test/libsolidity/ASTJSON/enum_value.json b/test/libsolidity/ASTJSON/enum_value.json index 21afd9a78c4a..a8562c4d497f 100644 --- a/test/libsolidity/ASTJSON/enum_value.json +++ b/test/libsolidity/ASTJSON/enum_value.json @@ -1,57 +1,57 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 4 - ] - }, - "id" : 5, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 4, - "linearizedBaseContracts" : - [ - 4 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "canonicalName" : "C.E", - "id" : 3, - "members" : - [ - { - "id" : 1, - "name" : "A", - "nodeType" : "EnumValue", - "src" : "22:1:1" - }, - { - "id" : 2, - "name" : "B", - "nodeType" : "EnumValue", - "src" : "25:1:1" - } - ], - "name" : "E", - "nodeType" : "EnumDefinition", - "src" : "13:15:1" - } - ], - "scope" : 5, - "src" : "0:30:1" - } - ], - "src" : "0:31:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 4 + ] + }, + "id": 5, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 4, + "linearizedBaseContracts": + [ + 4 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "canonicalName": "C.E", + "id": 3, + "members": + [ + { + "id": 1, + "name": "A", + "nodeType": "EnumValue", + "src": "22:1:1" + }, + { + "id": 2, + "name": "B", + "nodeType": "EnumValue", + "src": "25:1:1" + } + ], + "name": "E", + "nodeType": "EnumDefinition", + "src": "13:15:1" + } + ], + "scope": 5, + "src": "0:30:1" + } + ], + "src": "0:31:1" } diff --git a/test/libsolidity/ASTJSON/enum_value_legacy.json b/test/libsolidity/ASTJSON/enum_value_legacy.json index d7782969bda7..9bc5319bfc66 100644 --- a/test/libsolidity/ASTJSON/enum_value_legacy.json +++ b/test/libsolidity/ASTJSON/enum_value_legacy.json @@ -1,78 +1,78 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 4 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 4 - ], - "name" : "C", - "scope" : 5 - }, - "children" : - [ - { - "attributes" : - { - "canonicalName" : "C.E", - "name" : "E" - }, - "children" : - [ - { - "attributes" : - { - "name" : "A" - }, - "id" : 1, - "name" : "EnumValue", - "src" : "22:1:1" - }, - { - "attributes" : - { - "name" : "B" - }, - "id" : 2, - "name" : "EnumValue", - "src" : "25:1:1" - } - ], - "id" : 3, - "name" : "EnumDefinition", - "src" : "13:15:1" - } - ], - "id" : 4, - "name" : "ContractDefinition", - "src" : "0:30:1" - } - ], - "id" : 5, - "name" : "SourceUnit", - "src" : "0:31:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 4 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 4 + ], + "name": "C", + "scope": 5 + }, + "children": + [ + { + "attributes": + { + "canonicalName": "C.E", + "name": "E" + }, + "children": + [ + { + "attributes": + { + "name": "A" + }, + "id": 1, + "name": "EnumValue", + "src": "22:1:1" + }, + { + "attributes": + { + "name": "B" + }, + "id": 2, + "name": "EnumValue", + "src": "25:1:1" + } + ], + "id": 3, + "name": "EnumDefinition", + "src": "13:15:1" + } + ], + "id": 4, + "name": "ContractDefinition", + "src": "0:30:1" + } + ], + "id": 5, + "name": "SourceUnit", + "src": "0:31:1" } diff --git a/test/libsolidity/ASTJSON/event_definition.json b/test/libsolidity/ASTJSON/event_definition.json index 029062c32276..45f16ba85b5a 100644 --- a/test/libsolidity/ASTJSON/event_definition.json +++ b/test/libsolidity/ASTJSON/event_definition.json @@ -1,50 +1,50 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 3 - ] - }, - "id" : 4, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 3, - "linearizedBaseContracts" : - [ - 3 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "anonymous" : false, - "documentation" : null, - "id" : 2, - "name" : "E", - "nodeType" : "EventDefinition", - "parameters" : - { - "id" : 1, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "20:2:1" - }, - "src" : "13:10:1" - } - ], - "scope" : 4, - "src" : "0:25:1" - } - ], - "src" : "0:26:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 3 + ] + }, + "id": 4, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 3, + "linearizedBaseContracts": + [ + 3 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "anonymous": false, + "documentation": null, + "id": 2, + "name": "E", + "nodeType": "EventDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "20:2:1" + }, + "src": "13:10:1" + } + ], + "scope": 4, + "src": "0:25:1" + } + ], + "src": "0:26:1" } diff --git a/test/libsolidity/ASTJSON/event_definition_legacy.json b/test/libsolidity/ASTJSON/event_definition_legacy.json index f5967bf4eb61..5f0859fea600 100644 --- a/test/libsolidity/ASTJSON/event_definition_legacy.json +++ b/test/libsolidity/ASTJSON/event_definition_legacy.json @@ -1,74 +1,74 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 3 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 3 - ], - "name" : "C", - "scope" : 4 - }, - "children" : - [ - { - "attributes" : - { - "anonymous" : false, - "documentation" : null, - "name" : "E" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 1, - "name" : "ParameterList", - "src" : "20:2:1" - } - ], - "id" : 2, - "name" : "EventDefinition", - "src" : "13:10:1" - } - ], - "id" : 3, - "name" : "ContractDefinition", - "src" : "0:25:1" - } - ], - "id" : 4, - "name" : "SourceUnit", - "src" : "0:26:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 3 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 3 + ], + "name": "C", + "scope": 4 + }, + "children": + [ + { + "attributes": + { + "anonymous": false, + "documentation": null, + "name": "E" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 1, + "name": "ParameterList", + "src": "20:2:1" + } + ], + "id": 2, + "name": "EventDefinition", + "src": "13:10:1" + } + ], + "id": 3, + "name": "ContractDefinition", + "src": "0:25:1" + } + ], + "id": 4, + "name": "SourceUnit", + "src": "0:26:1" } diff --git a/test/libsolidity/ASTJSON/fallback.json b/test/libsolidity/ASTJSON/fallback.json index 6374051d498a..2d3d8e09e4be 100644 --- a/test/libsolidity/ASTJSON/fallback.json +++ b/test/libsolidity/ASTJSON/fallback.json @@ -1,71 +1,71 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 5 - ] - }, - "id" : 6, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 5, - "linearizedBaseContracts" : - [ - 5 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 3, - "nodeType" : "Block", - "src" : "43:5:1", - "statements" : [] - }, - "documentation" : null, - "id" : 4, - "implemented" : true, - "kind" : "fallback", - "modifiers" : [], - "name" : "", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 1, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "23:2:1" - }, - "returnParameters" : - { - "id" : 2, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "43:0:1" - }, - "scope" : 5, - "src" : "15:33:1", - "stateMutability" : "payable", - "superFunction" : null, - "visibility" : "external" - } - ], - "scope" : 6, - "src" : "0:50:1" - } - ], - "src" : "0:51:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + }, + "id": 6, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "43:5:1", + "statements": [] + }, + "documentation": null, + "id": 4, + "implemented": true, + "kind": "fallback", + "modifiers": [], + "name": "", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "43:0:1" + }, + "scope": 5, + "src": "15:33:1", + "stateMutability": "payable", + "superFunction": null, + "visibility": "external" + } + ], + "scope": 6, + "src": "0:50:1" + } + ], + "src": "0:51:1" } diff --git a/test/libsolidity/ASTJSON/fallback_legacy.json b/test/libsolidity/ASTJSON/fallback_legacy.json index 4e31a33ea770..5e74f49fddcc 100644 --- a/test/libsolidity/ASTJSON/fallback_legacy.json +++ b/test/libsolidity/ASTJSON/fallback_legacy.json @@ -1,111 +1,111 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 5 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 5 - ], - "name" : "C", - "scope" : 6 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "fallback", - "modifiers" : - [ - null - ], - "name" : "", - "overrides" : null, - "scope" : 5, - "stateMutability" : "payable", - "superFunction" : null, - "visibility" : "external" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 1, - "name" : "ParameterList", - "src" : "23:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 2, - "name" : "ParameterList", - "src" : "43:0:1" - }, - { - "attributes" : - { - "statements" : - [ - null - ] - }, - "children" : [], - "id" : 3, - "name" : "Block", - "src" : "43:5:1" - } - ], - "id" : 4, - "name" : "FunctionDefinition", - "src" : "15:33:1" - } - ], - "id" : 5, - "name" : "ContractDefinition", - "src" : "0:50:1" - } - ], - "id" : 6, - "name" : "SourceUnit", - "src" : "0:51:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "scope": 6 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "fallback", + "modifiers": + [ + null + ], + "name": "", + "overrides": null, + "scope": 5, + "stateMutability": "payable", + "superFunction": null, + "visibility": "external" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 1, + "name": "ParameterList", + "src": "23:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 2, + "name": "ParameterList", + "src": "43:0:1" + }, + { + "attributes": + { + "statements": + [ + null + ] + }, + "children": [], + "id": 3, + "name": "Block", + "src": "43:5:1" + } + ], + "id": 4, + "name": "FunctionDefinition", + "src": "15:33:1" + } + ], + "id": 5, + "name": "ContractDefinition", + "src": "0:50:1" + } + ], + "id": 6, + "name": "SourceUnit", + "src": "0:51:1" } diff --git a/test/libsolidity/ASTJSON/fallback_payable.json b/test/libsolidity/ASTJSON/fallback_payable.json index 49a7a33a904e..4127251c0f33 100644 --- a/test/libsolidity/ASTJSON/fallback_payable.json +++ b/test/libsolidity/ASTJSON/fallback_payable.json @@ -1,71 +1,71 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 5 - ] - }, - "id" : 6, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 5, - "linearizedBaseContracts" : - [ - 5 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 3, - "nodeType" : "Block", - "src" : "34:2:1", - "statements" : [] - }, - "documentation" : null, - "id" : 4, - "implemented" : true, - "kind" : "fallback", - "modifiers" : [], - "name" : "", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 1, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "22:2:1" - }, - "returnParameters" : - { - "id" : 2, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "34:0:1" - }, - "scope" : 5, - "src" : "14:22:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "external" - } - ], - "scope" : 6, - "src" : "0:38:1" - } - ], - "src" : "0:39:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + }, + "id": 6, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "34:2:1", + "statements": [] + }, + "documentation": null, + "id": 4, + "implemented": true, + "kind": "fallback", + "modifiers": [], + "name": "", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "22:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "34:0:1" + }, + "scope": 5, + "src": "14:22:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + } + ], + "scope": 6, + "src": "0:38:1" + } + ], + "src": "0:39:1" } diff --git a/test/libsolidity/ASTJSON/fallback_payable_legacy.json b/test/libsolidity/ASTJSON/fallback_payable_legacy.json index af148555b4ec..76671ce91e30 100644 --- a/test/libsolidity/ASTJSON/fallback_payable_legacy.json +++ b/test/libsolidity/ASTJSON/fallback_payable_legacy.json @@ -1,111 +1,111 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 5 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 5 - ], - "name" : "C", - "scope" : 6 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "fallback", - "modifiers" : - [ - null - ], - "name" : "", - "overrides" : null, - "scope" : 5, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "external" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 1, - "name" : "ParameterList", - "src" : "22:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 2, - "name" : "ParameterList", - "src" : "34:0:1" - }, - { - "attributes" : - { - "statements" : - [ - null - ] - }, - "children" : [], - "id" : 3, - "name" : "Block", - "src" : "34:2:1" - } - ], - "id" : 4, - "name" : "FunctionDefinition", - "src" : "14:22:1" - } - ], - "id" : 5, - "name" : "ContractDefinition", - "src" : "0:38:1" - } - ], - "id" : 6, - "name" : "SourceUnit", - "src" : "0:39:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "scope": 6 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "fallback", + "modifiers": + [ + null + ], + "name": "", + "overrides": null, + "scope": 5, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "external" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 1, + "name": "ParameterList", + "src": "22:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 2, + "name": "ParameterList", + "src": "34:0:1" + }, + { + "attributes": + { + "statements": + [ + null + ] + }, + "children": [], + "id": 3, + "name": "Block", + "src": "34:2:1" + } + ], + "id": 4, + "name": "FunctionDefinition", + "src": "14:22:1" + } + ], + "id": 5, + "name": "ContractDefinition", + "src": "0:38:1" + } + ], + "id": 6, + "name": "SourceUnit", + "src": "0:39:1" } diff --git a/test/libsolidity/ASTJSON/function_type.json b/test/libsolidity/ASTJSON/function_type.json index 8e60d2ef160a..62278a75c700 100644 --- a/test/libsolidity/ASTJSON/function_type.json +++ b/test/libsolidity/ASTJSON/function_type.json @@ -1,229 +1,229 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 17 - ] - }, - "id" : 18, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 17, - "linearizedBaseContracts" : - [ - 17 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 15, - "nodeType" : "Block", - "src" : "120:2:1", - "statements" : [] - }, - "documentation" : null, - "id" : 16, - "implemented" : true, - "kind" : "function", - "modifiers" : [], - "name" : "f", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 7, - "nodeType" : "ParameterList", - "parameters" : - [ - { - "constant" : false, - "id" : 6, - "name" : "x", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 16, - "src" : "24:44:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_function_external_payable$__$returns$_t_uint256_$", - "typeString" : "function () payable external returns (uint256)" - }, - "typeName" : - { - "id" : 5, - "nodeType" : "FunctionTypeName", - "parameterTypes" : - { - "id" : 1, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "32:2:1" - }, - "returnParameterTypes" : - { - "id" : 4, - "nodeType" : "ParameterList", - "parameters" : - [ - { - "constant" : false, - "id" : 3, - "name" : "", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 5, - "src" : "61:4:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - }, - "typeName" : - { - "id" : 2, - "name" : "uint", - "nodeType" : "ElementaryTypeName", - "src" : "61:4:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "src" : "60:6:1" - }, - "src" : "24:44:1", - "stateMutability" : "payable", - "typeDescriptions" : - { - "typeIdentifier" : "t_function_external_payable$__$returns$_t_uint256_$", - "typeString" : "function () payable external returns (uint256)" - }, - "visibility" : "external" - }, - "value" : null, - "visibility" : "internal" - } - ], - "src" : "23:46:1" - }, - "returnParameters" : - { - "id" : 14, - "nodeType" : "ParameterList", - "parameters" : - [ - { - "constant" : false, - "id" : 13, - "name" : "", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 16, - "src" : "79:40:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_function_external_view$__$returns$_t_uint256_$", - "typeString" : "function () view external returns (uint256)" - }, - "typeName" : - { - "id" : 12, - "nodeType" : "FunctionTypeName", - "parameterTypes" : - { - "id" : 8, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "87:2:1" - }, - "returnParameterTypes" : - { - "id" : 11, - "nodeType" : "ParameterList", - "parameters" : - [ - { - "constant" : false, - "id" : 10, - "name" : "", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 12, - "src" : "113:4:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - }, - "typeName" : - { - "id" : 9, - "name" : "uint", - "nodeType" : "ElementaryTypeName", - "src" : "113:4:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "src" : "112:6:1" - }, - "src" : "79:40:1", - "stateMutability" : "view", - "typeDescriptions" : - { - "typeIdentifier" : "t_function_external_view$__$returns$_t_uint256_$", - "typeString" : "function () view external returns (uint256)" - }, - "visibility" : "external" - }, - "value" : null, - "visibility" : "internal" - } - ], - "src" : "78:41:1" - }, - "scope" : 17, - "src" : "13:109:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - } - ], - "scope" : 18, - "src" : "0:124:1" - } - ], - "src" : "0:125:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 17 + ] + }, + "id": 18, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 17, + "linearizedBaseContracts": + [ + 17 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 15, + "nodeType": "Block", + "src": "120:2:1", + "statements": [] + }, + "documentation": null, + "id": 16, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 7, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 6, + "name": "x", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 16, + "src": "24:44:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_payable$__$returns$_t_uint256_$", + "typeString": "function () payable external returns (uint256)" + }, + "typeName": + { + "id": 5, + "nodeType": "FunctionTypeName", + "parameterTypes": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "32:2:1" + }, + "returnParameterTypes": + { + "id": 4, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 3, + "name": "", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 5, + "src": "61:4:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 2, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "61:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "60:6:1" + }, + "src": "24:44:1", + "stateMutability": "payable", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_payable$__$returns$_t_uint256_$", + "typeString": "function () payable external returns (uint256)" + }, + "visibility": "external" + }, + "value": null, + "visibility": "internal" + } + ], + "src": "23:46:1" + }, + "returnParameters": + { + "id": 14, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 13, + "name": "", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 16, + "src": "79:40:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_view$__$returns$_t_uint256_$", + "typeString": "function () view external returns (uint256)" + }, + "typeName": + { + "id": 12, + "nodeType": "FunctionTypeName", + "parameterTypes": + { + "id": 8, + "nodeType": "ParameterList", + "parameters": [], + "src": "87:2:1" + }, + "returnParameterTypes": + { + "id": 11, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 10, + "name": "", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 12, + "src": "113:4:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 9, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "113:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "112:6:1" + }, + "src": "79:40:1", + "stateMutability": "view", + "typeDescriptions": + { + "typeIdentifier": "t_function_external_view$__$returns$_t_uint256_$", + "typeString": "function () view external returns (uint256)" + }, + "visibility": "external" + }, + "value": null, + "visibility": "internal" + } + ], + "src": "78:41:1" + }, + "scope": 17, + "src": "13:109:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 18, + "src": "0:124:1" + } + ], + "src": "0:125:1" } diff --git a/test/libsolidity/ASTJSON/function_type_legacy.json b/test/libsolidity/ASTJSON/function_type_legacy.json index 90b5a8e4d701..1e200c05c9ef 100644 --- a/test/libsolidity/ASTJSON/function_type_legacy.json +++ b/test/libsolidity/ASTJSON/function_type_legacy.json @@ -1,271 +1,271 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 17 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 17 - ], - "name" : "C", - "scope" : 18 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "f", - "overrides" : null, - "scope" : 17, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "x", - "overrides" : null, - "scope" : 16, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "function () payable external returns (uint256)", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "stateMutability" : "payable", - "type" : "function () payable external returns (uint256)", - "visibility" : "external" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 1, - "name" : "ParameterList", - "src" : "32:2:1" - }, - { - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "", - "overrides" : null, - "scope" : 5, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "uint256", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "name" : "uint", - "type" : "uint256" - }, - "id" : 2, - "name" : "ElementaryTypeName", - "src" : "61:4:1" - } - ], - "id" : 3, - "name" : "VariableDeclaration", - "src" : "61:4:1" - } - ], - "id" : 4, - "name" : "ParameterList", - "src" : "60:6:1" - } - ], - "id" : 5, - "name" : "FunctionTypeName", - "src" : "24:44:1" - } - ], - "id" : 6, - "name" : "VariableDeclaration", - "src" : "24:44:1" - } - ], - "id" : 7, - "name" : "ParameterList", - "src" : "23:46:1" - }, - { - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "", - "overrides" : null, - "scope" : 16, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "function () view external returns (uint256)", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "stateMutability" : "view", - "type" : "function () view external returns (uint256)", - "visibility" : "external" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 8, - "name" : "ParameterList", - "src" : "87:2:1" - }, - { - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "", - "overrides" : null, - "scope" : 12, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "uint256", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "name" : "uint", - "type" : "uint256" - }, - "id" : 9, - "name" : "ElementaryTypeName", - "src" : "113:4:1" - } - ], - "id" : 10, - "name" : "VariableDeclaration", - "src" : "113:4:1" - } - ], - "id" : 11, - "name" : "ParameterList", - "src" : "112:6:1" - } - ], - "id" : 12, - "name" : "FunctionTypeName", - "src" : "79:40:1" - } - ], - "id" : 13, - "name" : "VariableDeclaration", - "src" : "79:40:1" - } - ], - "id" : 14, - "name" : "ParameterList", - "src" : "78:41:1" - }, - { - "attributes" : - { - "statements" : - [ - null - ] - }, - "children" : [], - "id" : 15, - "name" : "Block", - "src" : "120:2:1" - } - ], - "id" : 16, - "name" : "FunctionDefinition", - "src" : "13:109:1" - } - ], - "id" : 17, - "name" : "ContractDefinition", - "src" : "0:124:1" - } - ], - "id" : 18, - "name" : "SourceUnit", - "src" : "0:125:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 17 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 17 + ], + "name": "C", + "scope": 18 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "f", + "overrides": null, + "scope": 17, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "children": + [ + { + "attributes": + { + "constant": false, + "name": "x", + "overrides": null, + "scope": 16, + "stateVariable": false, + "storageLocation": "default", + "type": "function () payable external returns (uint256)", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "stateMutability": "payable", + "type": "function () payable external returns (uint256)", + "visibility": "external" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 1, + "name": "ParameterList", + "src": "32:2:1" + }, + { + "children": + [ + { + "attributes": + { + "constant": false, + "name": "", + "overrides": null, + "scope": 5, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 2, + "name": "ElementaryTypeName", + "src": "61:4:1" + } + ], + "id": 3, + "name": "VariableDeclaration", + "src": "61:4:1" + } + ], + "id": 4, + "name": "ParameterList", + "src": "60:6:1" + } + ], + "id": 5, + "name": "FunctionTypeName", + "src": "24:44:1" + } + ], + "id": 6, + "name": "VariableDeclaration", + "src": "24:44:1" + } + ], + "id": 7, + "name": "ParameterList", + "src": "23:46:1" + }, + { + "children": + [ + { + "attributes": + { + "constant": false, + "name": "", + "overrides": null, + "scope": 16, + "stateVariable": false, + "storageLocation": "default", + "type": "function () view external returns (uint256)", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "stateMutability": "view", + "type": "function () view external returns (uint256)", + "visibility": "external" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 8, + "name": "ParameterList", + "src": "87:2:1" + }, + { + "children": + [ + { + "attributes": + { + "constant": false, + "name": "", + "overrides": null, + "scope": 12, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 9, + "name": "ElementaryTypeName", + "src": "113:4:1" + } + ], + "id": 10, + "name": "VariableDeclaration", + "src": "113:4:1" + } + ], + "id": 11, + "name": "ParameterList", + "src": "112:6:1" + } + ], + "id": 12, + "name": "FunctionTypeName", + "src": "79:40:1" + } + ], + "id": 13, + "name": "VariableDeclaration", + "src": "79:40:1" + } + ], + "id": 14, + "name": "ParameterList", + "src": "78:41:1" + }, + { + "attributes": + { + "statements": + [ + null + ] + }, + "children": [], + "id": 15, + "name": "Block", + "src": "120:2:1" + } + ], + "id": 16, + "name": "FunctionDefinition", + "src": "13:109:1" + } + ], + "id": 17, + "name": "ContractDefinition", + "src": "0:124:1" + } + ], + "id": 18, + "name": "SourceUnit", + "src": "0:125:1" } diff --git a/test/libsolidity/ASTJSON/global_enum.json b/test/libsolidity/ASTJSON/global_enum.json index ccf3760ffabf..1b0ffe3778d9 100644 --- a/test/libsolidity/ASTJSON/global_enum.json +++ b/test/libsolidity/ASTJSON/global_enum.json @@ -1,32 +1,32 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "E" : - [ - 2 - ] - }, - "id" : 3, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "canonicalName" : "E", - "id" : 2, - "members" : - [ - { - "id" : 1, - "name" : "A", - "nodeType" : "EnumValue", - "src" : "9:1:1" - } - ], - "name" : "E", - "nodeType" : "EnumDefinition", - "src" : "0:12:1" - } - ], - "src" : "0:13:1" + "absolutePath": "a", + "exportedSymbols": + { + "E": + [ + 2 + ] + }, + "id": 3, + "nodeType": "SourceUnit", + "nodes": + [ + { + "canonicalName": "E", + "id": 2, + "members": + [ + { + "id": 1, + "name": "A", + "nodeType": "EnumValue", + "src": "9:1:1" + } + ], + "name": "E", + "nodeType": "EnumDefinition", + "src": "0:12:1" + } + ], + "src": "0:13:1" } diff --git a/test/libsolidity/ASTJSON/global_enum_legacy.json b/test/libsolidity/ASTJSON/global_enum_legacy.json index fc49b6cbed2e..f29649018688 100644 --- a/test/libsolidity/ASTJSON/global_enum_legacy.json +++ b/test/libsolidity/ASTJSON/global_enum_legacy.json @@ -1,41 +1,41 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "E" : - [ - 2 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "canonicalName" : "E", - "name" : "E" - }, - "children" : - [ - { - "attributes" : - { - "name" : "A" - }, - "id" : 1, - "name" : "EnumValue", - "src" : "9:1:1" - } - ], - "id" : 2, - "name" : "EnumDefinition", - "src" : "0:12:1" - } - ], - "id" : 3, - "name" : "SourceUnit", - "src" : "0:13:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "E": + [ + 2 + ] + } + }, + "children": + [ + { + "attributes": + { + "canonicalName": "E", + "name": "E" + }, + "children": + [ + { + "attributes": + { + "name": "A" + }, + "id": 1, + "name": "EnumValue", + "src": "9:1:1" + } + ], + "id": 2, + "name": "EnumDefinition", + "src": "0:12:1" + } + ], + "id": 3, + "name": "SourceUnit", + "src": "0:13:1" } diff --git a/test/libsolidity/ASTJSON/global_struct.json b/test/libsolidity/ASTJSON/global_struct.json index 63c4e463e11c..6eaaee8d9cea 100644 --- a/test/libsolidity/ASTJSON/global_struct.json +++ b/test/libsolidity/ASTJSON/global_struct.json @@ -1,58 +1,58 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "S" : - [ - 3 - ] - }, - "id" : 4, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "canonicalName" : "S", - "id" : 3, - "members" : - [ - { - "constant" : false, - "id" : 2, - "name" : "a", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 3, - "src" : "11:9:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - }, - "typeName" : - { - "id" : 1, - "name" : "uint256", - "nodeType" : "ElementaryTypeName", - "src" : "11:7:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "name" : "S", - "nodeType" : "StructDefinition", - "scope" : 4, - "src" : "0:23:1", - "visibility" : "public" - } - ], - "src" : "0:24:1" + "absolutePath": "a", + "exportedSymbols": + { + "S": + [ + 3 + ] + }, + "id": 4, + "nodeType": "SourceUnit", + "nodes": + [ + { + "canonicalName": "S", + "id": 3, + "members": + [ + { + "constant": false, + "id": 2, + "name": "a", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 3, + "src": "11:9:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "11:7:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "name": "S", + "nodeType": "StructDefinition", + "scope": 4, + "src": "0:23:1", + "visibility": "public" + } + ], + "src": "0:24:1" } diff --git a/test/libsolidity/ASTJSON/global_struct_legacy.json b/test/libsolidity/ASTJSON/global_struct_legacy.json index b54a31c0dc78..fd68cee577b9 100644 --- a/test/libsolidity/ASTJSON/global_struct_legacy.json +++ b/test/libsolidity/ASTJSON/global_struct_legacy.json @@ -1,64 +1,64 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "S" : - [ - 3 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "canonicalName" : "S", - "name" : "S", - "scope" : 4, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "a", - "overrides" : null, - "scope" : 3, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "uint256", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "name" : "uint256", - "type" : "uint256" - }, - "id" : 1, - "name" : "ElementaryTypeName", - "src" : "11:7:1" - } - ], - "id" : 2, - "name" : "VariableDeclaration", - "src" : "11:9:1" - } - ], - "id" : 3, - "name" : "StructDefinition", - "src" : "0:23:1" - } - ], - "id" : 4, - "name" : "SourceUnit", - "src" : "0:24:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "S": + [ + 3 + ] + } + }, + "children": + [ + { + "attributes": + { + "canonicalName": "S", + "name": "S", + "scope": 4, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "a", + "overrides": null, + "scope": 3, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "uint256", + "type": "uint256" + }, + "id": 1, + "name": "ElementaryTypeName", + "src": "11:7:1" + } + ], + "id": 2, + "name": "VariableDeclaration", + "src": "11:9:1" + } + ], + "id": 3, + "name": "StructDefinition", + "src": "0:23:1" + } + ], + "id": 4, + "name": "SourceUnit", + "src": "0:24:1" } diff --git a/test/libsolidity/ASTJSON/inheritance_specifier.json b/test/libsolidity/ASTJSON/inheritance_specifier.json index edef8677978c..9de5f68b8604 100644 --- a/test/libsolidity/ASTJSON/inheritance_specifier.json +++ b/test/libsolidity/ASTJSON/inheritance_specifier.json @@ -1,80 +1,80 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C1" : - [ - 1 - ], - "C2" : - [ - 4 - ] - }, - "id" : 5, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 1, - "linearizedBaseContracts" : - [ - 1 - ], - "name" : "C1", - "nodeType" : "ContractDefinition", - "nodes" : [], - "scope" : 5, - "src" : "0:14:1" - }, - { - "baseContracts" : - [ - { - "arguments" : null, - "baseName" : - { - "contractScope" : null, - "id" : 2, - "name" : "C1", - "nodeType" : "UserDefinedTypeName", - "referencedDeclaration" : 1, - "src" : "30:2:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_contract$_C1_$1", - "typeString" : "contract C1" - } - }, - "id" : 3, - "nodeType" : "InheritanceSpecifier", - "src" : "30:2:1" - } - ], - "contractDependencies" : - [ - 1 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 4, - "linearizedBaseContracts" : - [ - 4, - 1 - ], - "name" : "C2", - "nodeType" : "ContractDefinition", - "nodes" : [], - "scope" : 5, - "src" : "15:20:1" - } - ], - "src" : "0:36:1" + "absolutePath": "a", + "exportedSymbols": + { + "C1": + [ + 1 + ], + "C2": + [ + 4 + ] + }, + "id": 5, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 1, + "linearizedBaseContracts": + [ + 1 + ], + "name": "C1", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 5, + "src": "0:14:1" + }, + { + "baseContracts": + [ + { + "arguments": null, + "baseName": + { + "contractScope": null, + "id": 2, + "name": "C1", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 1, + "src": "30:2:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_C1_$1", + "typeString": "contract C1" + } + }, + "id": 3, + "nodeType": "InheritanceSpecifier", + "src": "30:2:1" + } + ], + "contractDependencies": + [ + 1 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 4, + "linearizedBaseContracts": + [ + 4, + 1 + ], + "name": "C2", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 5, + "src": "15:20:1" + } + ], + "src": "0:36:1" } diff --git a/test/libsolidity/ASTJSON/inheritance_specifier_legacy.json b/test/libsolidity/ASTJSON/inheritance_specifier_legacy.json index 0fcf293944e1..8f688a4d98a1 100644 --- a/test/libsolidity/ASTJSON/inheritance_specifier_legacy.json +++ b/test/libsolidity/ASTJSON/inheritance_specifier_legacy.json @@ -1,105 +1,105 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C1" : - [ - 1 - ], - "C2" : - [ - 4 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 1 - ], - "name" : "C1", - "nodes" : - [ - null - ], - "scope" : 5 - }, - "id" : 1, - "name" : "ContractDefinition", - "src" : "0:14:1" - }, - { - "attributes" : - { - "contractDependencies" : - [ - 1 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 4, - 1 - ], - "name" : "C2", - "nodes" : - [ - null - ], - "scope" : 5 - }, - "children" : - [ - { - "attributes" : - { - "arguments" : null - }, - "children" : - [ - { - "attributes" : - { - "contractScope" : null, - "name" : "C1", - "referencedDeclaration" : 1, - "type" : "contract C1" - }, - "id" : 2, - "name" : "UserDefinedTypeName", - "src" : "30:2:1" - } - ], - "id" : 3, - "name" : "InheritanceSpecifier", - "src" : "30:2:1" - } - ], - "id" : 4, - "name" : "ContractDefinition", - "src" : "15:20:1" - } - ], - "id" : 5, - "name" : "SourceUnit", - "src" : "0:36:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C1": + [ + 1 + ], + "C2": + [ + 4 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 1 + ], + "name": "C1", + "nodes": + [ + null + ], + "scope": 5 + }, + "id": 1, + "name": "ContractDefinition", + "src": "0:14:1" + }, + { + "attributes": + { + "contractDependencies": + [ + 1 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 4, + 1 + ], + "name": "C2", + "nodes": + [ + null + ], + "scope": 5 + }, + "children": + [ + { + "attributes": + { + "arguments": null + }, + "children": + [ + { + "attributes": + { + "contractScope": null, + "name": "C1", + "referencedDeclaration": 1, + "type": "contract C1" + }, + "id": 2, + "name": "UserDefinedTypeName", + "src": "30:2:1" + } + ], + "id": 3, + "name": "InheritanceSpecifier", + "src": "30:2:1" + } + ], + "id": 4, + "name": "ContractDefinition", + "src": "15:20:1" + } + ], + "id": 5, + "name": "SourceUnit", + "src": "0:36:1" } diff --git a/test/libsolidity/ASTJSON/long_type_name_binary_operation.json b/test/libsolidity/ASTJSON/long_type_name_binary_operation.json index acc60daf0604..11f85728924a 100644 --- a/test/libsolidity/ASTJSON/long_type_name_binary_operation.json +++ b/test/libsolidity/ASTJSON/long_type_name_binary_operation.json @@ -1,177 +1,177 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "c" : - [ - 11 - ] - }, - "id" : 12, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 11, - "linearizedBaseContracts" : - [ - 11 - ], - "name" : "c", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 9, - "nodeType" : "Block", - "src" : "33:19:1", - "statements" : - [ - { - "assignments" : - [ - 4 - ], - "declarations" : - [ - { - "constant" : false, - "id" : 4, - "name" : "a", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 9, - "src" : "35:6:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - }, - "typeName" : - { - "id" : 3, - "name" : "uint", - "nodeType" : "ElementaryTypeName", - "src" : "35:4:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "id" : 8, - "initialValue" : - { - "argumentTypes" : null, - "commonType" : - { - "typeIdentifier" : "t_rational_5_by_1", - "typeString" : "int_const 5" - }, - "id" : 7, - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "leftExpression" : - { - "argumentTypes" : null, - "hexValue" : "32", - "id" : 5, - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "kind" : "number", - "lValueRequested" : false, - "nodeType" : "Literal", - "src" : "44:1:1", - "subdenomination" : null, - "typeDescriptions" : - { - "typeIdentifier" : "t_rational_2_by_1", - "typeString" : "int_const 2" - }, - "value" : "2" - }, - "nodeType" : "BinaryOperation", - "operator" : "+", - "rightExpression" : - { - "argumentTypes" : null, - "hexValue" : "33", - "id" : 6, - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "kind" : "number", - "lValueRequested" : false, - "nodeType" : "Literal", - "src" : "48:1:1", - "subdenomination" : null, - "typeDescriptions" : - { - "typeIdentifier" : "t_rational_3_by_1", - "typeString" : "int_const 3" - }, - "value" : "3" - }, - "src" : "44:5:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_rational_5_by_1", - "typeString" : "int_const 5" - } - }, - "nodeType" : "VariableDeclarationStatement", - "src" : "35:14:1" - } - ] - }, - "documentation" : null, - "id" : 10, - "implemented" : true, - "kind" : "function", - "modifiers" : [], - "name" : "f", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 1, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "23:2:1" - }, - "returnParameters" : - { - "id" : 2, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "33:0:1" - }, - "scope" : 11, - "src" : "13:39:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - } - ], - "scope" : 12, - "src" : "0:54:1" - } - ], - "src" : "0:55:1" + "absolutePath": "a", + "exportedSymbols": + { + "c": + [ + 11 + ] + }, + "id": 12, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 11, + "linearizedBaseContracts": + [ + 11 + ], + "name": "c", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 9, + "nodeType": "Block", + "src": "33:19:1", + "statements": + [ + { + "assignments": + [ + 4 + ], + "declarations": + [ + { + "constant": false, + "id": 4, + "name": "a", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 9, + "src": "35:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 3, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "35:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8, + "initialValue": + { + "argumentTypes": null, + "commonType": + { + "typeIdentifier": "t_rational_5_by_1", + "typeString": "int_const 5" + }, + "id": 7, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "leftExpression": + { + "argumentTypes": null, + "hexValue": "32", + "id": 5, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "44:1:1", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "BinaryOperation", + "operator": "+", + "rightExpression": + { + "argumentTypes": null, + "hexValue": "33", + "id": 6, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "48:1:1", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_3_by_1", + "typeString": "int_const 3" + }, + "value": "3" + }, + "src": "44:5:1", + "typeDescriptions": + { + "typeIdentifier": "t_rational_5_by_1", + "typeString": "int_const 5" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "35:14:1" + } + ] + }, + "documentation": null, + "id": 10, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "33:0:1" + }, + "scope": 11, + "src": "13:39:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 12, + "src": "0:54:1" + } + ], + "src": "0:55:1" } diff --git a/test/libsolidity/ASTJSON/long_type_name_binary_operation_legacy.json b/test/libsolidity/ASTJSON/long_type_name_binary_operation_legacy.json index cccf82f6dce5..5bc681554117 100644 --- a/test/libsolidity/ASTJSON/long_type_name_binary_operation_legacy.json +++ b/test/libsolidity/ASTJSON/long_type_name_binary_operation_legacy.json @@ -1,210 +1,210 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "c" : - [ - 11 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 11 - ], - "name" : "c", - "scope" : 12 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "f", - "overrides" : null, - "scope" : 11, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 1, - "name" : "ParameterList", - "src" : "23:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 2, - "name" : "ParameterList", - "src" : "33:0:1" - }, - { - "children" : - [ - { - "attributes" : - { - "assignments" : - [ - 4 - ] - }, - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "a", - "overrides" : null, - "scope" : 9, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "uint256", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "name" : "uint", - "type" : "uint256" - }, - "id" : 3, - "name" : "ElementaryTypeName", - "src" : "35:4:1" - } - ], - "id" : 4, - "name" : "VariableDeclaration", - "src" : "35:6:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "commonType" : - { - "typeIdentifier" : "t_rational_5_by_1", - "typeString" : "int_const 5" - }, - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "operator" : "+", - "type" : "int_const 5" - }, - "children" : - [ - { - "attributes" : - { - "argumentTypes" : null, - "hexvalue" : "32", - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "subdenomination" : null, - "token" : "number", - "type" : "int_const 2", - "value" : "2" - }, - "id" : 5, - "name" : "Literal", - "src" : "44:1:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "hexvalue" : "33", - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "subdenomination" : null, - "token" : "number", - "type" : "int_const 3", - "value" : "3" - }, - "id" : 6, - "name" : "Literal", - "src" : "48:1:1" - } - ], - "id" : 7, - "name" : "BinaryOperation", - "src" : "44:5:1" - } - ], - "id" : 8, - "name" : "VariableDeclarationStatement", - "src" : "35:14:1" - } - ], - "id" : 9, - "name" : "Block", - "src" : "33:19:1" - } - ], - "id" : 10, - "name" : "FunctionDefinition", - "src" : "13:39:1" - } - ], - "id" : 11, - "name" : "ContractDefinition", - "src" : "0:54:1" - } - ], - "id" : 12, - "name" : "SourceUnit", - "src" : "0:55:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "c": + [ + 11 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 11 + ], + "name": "c", + "scope": 12 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "f", + "overrides": null, + "scope": 11, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 1, + "name": "ParameterList", + "src": "23:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 2, + "name": "ParameterList", + "src": "33:0:1" + }, + { + "children": + [ + { + "attributes": + { + "assignments": + [ + 4 + ] + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "a", + "overrides": null, + "scope": 9, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 3, + "name": "ElementaryTypeName", + "src": "35:4:1" + } + ], + "id": 4, + "name": "VariableDeclaration", + "src": "35:6:1" + }, + { + "attributes": + { + "argumentTypes": null, + "commonType": + { + "typeIdentifier": "t_rational_5_by_1", + "typeString": "int_const 5" + }, + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "operator": "+", + "type": "int_const 5" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "32", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 2", + "value": "2" + }, + "id": 5, + "name": "Literal", + "src": "44:1:1" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "33", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 3", + "value": "3" + }, + "id": 6, + "name": "Literal", + "src": "48:1:1" + } + ], + "id": 7, + "name": "BinaryOperation", + "src": "44:5:1" + } + ], + "id": 8, + "name": "VariableDeclarationStatement", + "src": "35:14:1" + } + ], + "id": 9, + "name": "Block", + "src": "33:19:1" + } + ], + "id": 10, + "name": "FunctionDefinition", + "src": "13:39:1" + } + ], + "id": 11, + "name": "ContractDefinition", + "src": "0:54:1" + } + ], + "id": 12, + "name": "SourceUnit", + "src": "0:55:1" } diff --git a/test/libsolidity/ASTJSON/long_type_name_identifier.json b/test/libsolidity/ASTJSON/long_type_name_identifier.json index 595f5b6412cc..89bca274f4cd 100644 --- a/test/libsolidity/ASTJSON/long_type_name_identifier.json +++ b/test/libsolidity/ASTJSON/long_type_name_identifier.json @@ -1,184 +1,184 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "c" : - [ - 15 - ] - }, - "id" : 16, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 15, - "linearizedBaseContracts" : - [ - 15 - ], - "name" : "c", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "constant" : false, - "id" : 3, - "name" : "a", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 15, - "src" : "13:8:1", - "stateVariable" : true, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_array$_t_uint256_$dyn_storage", - "typeString" : "uint256[]" - }, - "typeName" : - { - "baseType" : - { - "id" : 1, - "name" : "uint", - "nodeType" : "ElementaryTypeName", - "src" : "13:4:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - } - }, - "id" : 2, - "length" : null, - "nodeType" : "ArrayTypeName", - "src" : "13:6:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_array$_t_uint256_$dyn_storage_ptr", - "typeString" : "uint256[]" - } - }, - "value" : null, - "visibility" : "internal" - }, - { - "body" : - { - "id" : 13, - "nodeType" : "Block", - "src" : "43:25:1", - "statements" : - [ - { - "assignments" : - [ - 10 - ], - "declarations" : - [ - { - "constant" : false, - "id" : 10, - "name" : "b", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 13, - "src" : "45:16:1", - "stateVariable" : false, - "storageLocation" : "storage", - "typeDescriptions" : - { - "typeIdentifier" : "t_array$_t_uint256_$dyn_storage_ptr", - "typeString" : "uint256[]" - }, - "typeName" : - { - "baseType" : - { - "id" : 8, - "name" : "uint", - "nodeType" : "ElementaryTypeName", - "src" : "45:4:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - } - }, - "id" : 9, - "length" : null, - "nodeType" : "ArrayTypeName", - "src" : "45:6:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_array$_t_uint256_$dyn_storage_ptr", - "typeString" : "uint256[]" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "id" : 12, - "initialValue" : - { - "argumentTypes" : null, - "id" : 11, - "name" : "a", - "nodeType" : "Identifier", - "overloadedDeclarations" : [], - "referencedDeclaration" : 3, - "src" : "64:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_array$_t_uint256_$dyn_storage", - "typeString" : "uint256[] storage ref" - } - }, - "nodeType" : "VariableDeclarationStatement", - "src" : "45:20:1" - } - ] - }, - "documentation" : null, - "id" : 14, - "implemented" : true, - "kind" : "function", - "modifiers" : [], - "name" : "f", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 4, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "33:2:1" - }, - "returnParameters" : - { - "id" : 5, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "43:0:1" - }, - "scope" : 15, - "src" : "23:45:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - } - ], - "scope" : 16, - "src" : "0:70:1" - } - ], - "src" : "0:71:1" + "absolutePath": "a", + "exportedSymbols": + { + "c": + [ + 15 + ] + }, + "id": 16, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 15, + "linearizedBaseContracts": + [ + 15 + ], + "name": "c", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "constant": false, + "id": 3, + "name": "a", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 15, + "src": "13:8:1", + "stateVariable": true, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage", + "typeString": "uint256[]" + }, + "typeName": + { + "baseType": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "13:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 2, + "length": null, + "nodeType": "ArrayTypeName", + "src": "13:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + }, + { + "body": + { + "id": 13, + "nodeType": "Block", + "src": "43:25:1", + "statements": + [ + { + "assignments": + [ + 10 + ], + "declarations": + [ + { + "constant": false, + "id": 10, + "name": "b", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 13, + "src": "45:16:1", + "stateVariable": false, + "storageLocation": "storage", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + }, + "typeName": + { + "baseType": + { + "id": 8, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "45:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 9, + "length": null, + "nodeType": "ArrayTypeName", + "src": "45:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 12, + "initialValue": + { + "argumentTypes": null, + "id": 11, + "name": "a", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3, + "src": "64:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage", + "typeString": "uint256[] storage ref" + } + }, + "nodeType": "VariableDeclarationStatement", + "src": "45:20:1" + } + ] + }, + "documentation": null, + "id": 14, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 4, + "nodeType": "ParameterList", + "parameters": [], + "src": "33:2:1" + }, + "returnParameters": + { + "id": 5, + "nodeType": "ParameterList", + "parameters": [], + "src": "43:0:1" + }, + "scope": 15, + "src": "23:45:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 16, + "src": "0:70:1" + } + ], + "src": "0:71:1" } diff --git a/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json b/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json index 1f222fe84b5f..8c933aa3138a 100644 --- a/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json +++ b/test/libsolidity/ASTJSON/long_type_name_identifier_legacy.json @@ -1,223 +1,223 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "c" : - [ - 15 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 15 - ], - "name" : "c", - "scope" : 16 - }, - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "a", - "overrides" : null, - "scope" : 15, - "stateVariable" : true, - "storageLocation" : "default", - "type" : "uint256[]", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "length" : null, - "type" : "uint256[]" - }, - "children" : - [ - { - "attributes" : - { - "name" : "uint", - "type" : "uint256" - }, - "id" : 1, - "name" : "ElementaryTypeName", - "src" : "13:4:1" - } - ], - "id" : 2, - "name" : "ArrayTypeName", - "src" : "13:6:1" - } - ], - "id" : 3, - "name" : "VariableDeclaration", - "src" : "13:8:1" - }, - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "f", - "overrides" : null, - "scope" : 15, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 4, - "name" : "ParameterList", - "src" : "33:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 5, - "name" : "ParameterList", - "src" : "43:0:1" - }, - { - "children" : - [ - { - "attributes" : - { - "assignments" : - [ - 10 - ] - }, - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "b", - "overrides" : null, - "scope" : 13, - "stateVariable" : false, - "storageLocation" : "storage", - "type" : "uint256[]", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "length" : null, - "type" : "uint256[]" - }, - "children" : - [ - { - "attributes" : - { - "name" : "uint", - "type" : "uint256" - }, - "id" : 8, - "name" : "ElementaryTypeName", - "src" : "45:4:1" - } - ], - "id" : 9, - "name" : "ArrayTypeName", - "src" : "45:6:1" - } - ], - "id" : 10, - "name" : "VariableDeclaration", - "src" : "45:16:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "overloadedDeclarations" : - [ - null - ], - "referencedDeclaration" : 3, - "type" : "uint256[] storage ref", - "value" : "a" - }, - "id" : 11, - "name" : "Identifier", - "src" : "64:1:1" - } - ], - "id" : 12, - "name" : "VariableDeclarationStatement", - "src" : "45:20:1" - } - ], - "id" : 13, - "name" : "Block", - "src" : "43:25:1" - } - ], - "id" : 14, - "name" : "FunctionDefinition", - "src" : "23:45:1" - } - ], - "id" : 15, - "name" : "ContractDefinition", - "src" : "0:70:1" - } - ], - "id" : 16, - "name" : "SourceUnit", - "src" : "0:71:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "c": + [ + 15 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 15 + ], + "name": "c", + "scope": 16 + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "a", + "overrides": null, + "scope": 15, + "stateVariable": true, + "storageLocation": "default", + "type": "uint256[]", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "length": null, + "type": "uint256[]" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 1, + "name": "ElementaryTypeName", + "src": "13:4:1" + } + ], + "id": 2, + "name": "ArrayTypeName", + "src": "13:6:1" + } + ], + "id": 3, + "name": "VariableDeclaration", + "src": "13:8:1" + }, + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "f", + "overrides": null, + "scope": 15, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 4, + "name": "ParameterList", + "src": "33:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 5, + "name": "ParameterList", + "src": "43:0:1" + }, + { + "children": + [ + { + "attributes": + { + "assignments": + [ + 10 + ] + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "b", + "overrides": null, + "scope": 13, + "stateVariable": false, + "storageLocation": "storage", + "type": "uint256[]", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "length": null, + "type": "uint256[]" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 8, + "name": "ElementaryTypeName", + "src": "45:4:1" + } + ], + "id": 9, + "name": "ArrayTypeName", + "src": "45:6:1" + } + ], + "id": 10, + "name": "VariableDeclaration", + "src": "45:16:1" + }, + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 3, + "type": "uint256[] storage ref", + "value": "a" + }, + "id": 11, + "name": "Identifier", + "src": "64:1:1" + } + ], + "id": 12, + "name": "VariableDeclarationStatement", + "src": "45:20:1" + } + ], + "id": 13, + "name": "Block", + "src": "43:25:1" + } + ], + "id": 14, + "name": "FunctionDefinition", + "src": "23:45:1" + } + ], + "id": 15, + "name": "ContractDefinition", + "src": "0:70:1" + } + ], + "id": 16, + "name": "SourceUnit", + "src": "0:71:1" } diff --git a/test/libsolidity/ASTJSON/modifier_definition.json b/test/libsolidity/ASTJSON/modifier_definition.json index 0e512e8049dd..89710117f685 100644 --- a/test/libsolidity/ASTJSON/modifier_definition.json +++ b/test/libsolidity/ASTJSON/modifier_definition.json @@ -1,176 +1,176 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 14 - ] - }, - "id" : 15, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 14, - "linearizedBaseContracts" : - [ - 14 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 5, - "nodeType" : "Block", - "src" : "32:6:1", - "statements" : - [ - { - "id" : 4, - "nodeType" : "PlaceholderStatement", - "src" : "34:1:1" - } - ] - }, - "documentation" : null, - "id" : 6, - "name" : "M", - "nodeType" : "ModifierDefinition", - "parameters" : - { - "id" : 3, - "nodeType" : "ParameterList", - "parameters" : - [ - { - "constant" : false, - "id" : 2, - "name" : "i", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 6, - "src" : "24:6:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - }, - "typeName" : - { - "id" : 1, - "name" : "uint", - "nodeType" : "ElementaryTypeName", - "src" : "24:4:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "src" : "23:8:1" - }, - "src" : "13:25:1", - "visibility" : "internal" - }, - { - "body" : - { - "id" : 12, - "nodeType" : "Block", - "src" : "64:2:1", - "statements" : [] - }, - "documentation" : null, - "id" : 13, - "implemented" : true, - "kind" : "function", - "modifiers" : - [ - { - "arguments" : - [ - { - "argumentTypes" : null, - "hexValue" : "31", - "id" : 9, - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "kind" : "number", - "lValueRequested" : false, - "nodeType" : "Literal", - "src" : "54:1:1", - "subdenomination" : null, - "typeDescriptions" : - { - "typeIdentifier" : "t_rational_1_by_1", - "typeString" : "int_const 1" - }, - "value" : "1" - } - ], - "id" : 10, - "modifierName" : - { - "argumentTypes" : null, - "id" : 8, - "name" : "M", - "nodeType" : "Identifier", - "overloadedDeclarations" : [], - "referencedDeclaration" : 6, - "src" : "52:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_modifier$_t_uint256_$", - "typeString" : "modifier (uint256)" - } - }, - "nodeType" : "ModifierInvocation", - "src" : "52:4:1" - } - ], - "name" : "F", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 7, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "49:2:1" - }, - "returnParameters" : - { - "id" : 11, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "64:0:1" - }, - "scope" : 14, - "src" : "39:27:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - } - ], - "scope" : 15, - "src" : "0:68:1" - } - ], - "src" : "0:69:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 14 + ] + }, + "id": 15, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 14, + "linearizedBaseContracts": + [ + 14 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 5, + "nodeType": "Block", + "src": "32:6:1", + "statements": + [ + { + "id": 4, + "nodeType": "PlaceholderStatement", + "src": "34:1:1" + } + ] + }, + "documentation": null, + "id": 6, + "name": "M", + "nodeType": "ModifierDefinition", + "parameters": + { + "id": 3, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2, + "name": "i", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 6, + "src": "24:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "24:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "23:8:1" + }, + "src": "13:25:1", + "visibility": "internal" + }, + { + "body": + { + "id": 12, + "nodeType": "Block", + "src": "64:2:1", + "statements": [] + }, + "documentation": null, + "id": 13, + "implemented": true, + "kind": "function", + "modifiers": + [ + { + "arguments": + [ + { + "argumentTypes": null, + "hexValue": "31", + "id": 9, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "54:1:1", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "id": 10, + "modifierName": + { + "argumentTypes": null, + "id": 8, + "name": "M", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 6, + "src": "52:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_modifier$_t_uint256_$", + "typeString": "modifier (uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "52:4:1" + } + ], + "name": "F", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 7, + "nodeType": "ParameterList", + "parameters": [], + "src": "49:2:1" + }, + "returnParameters": + { + "id": 11, + "nodeType": "ParameterList", + "parameters": [], + "src": "64:0:1" + }, + "scope": 14, + "src": "39:27:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 15, + "src": "0:68:1" + } + ], + "src": "0:69:1" } diff --git a/test/libsolidity/ASTJSON/modifier_definition_legacy.json b/test/libsolidity/ASTJSON/modifier_definition_legacy.json index 5bb91624ebfe..c3574404dfe4 100644 --- a/test/libsolidity/ASTJSON/modifier_definition_legacy.json +++ b/test/libsolidity/ASTJSON/modifier_definition_legacy.json @@ -1,214 +1,214 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 14 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 14 - ], - "name" : "C", - "scope" : 15 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "name" : "M", - "visibility" : "internal" - }, - "children" : - [ - { - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "i", - "overrides" : null, - "scope" : 6, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "uint256", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "name" : "uint", - "type" : "uint256" - }, - "id" : 1, - "name" : "ElementaryTypeName", - "src" : "24:4:1" - } - ], - "id" : 2, - "name" : "VariableDeclaration", - "src" : "24:6:1" - } - ], - "id" : 3, - "name" : "ParameterList", - "src" : "23:8:1" - }, - { - "children" : - [ - { - "id" : 4, - "name" : "PlaceholderStatement", - "src" : "34:1:1" - } - ], - "id" : 5, - "name" : "Block", - "src" : "32:6:1" - } - ], - "id" : 6, - "name" : "ModifierDefinition", - "src" : "13:25:1" - }, - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "name" : "F", - "overrides" : null, - "scope" : 14, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 7, - "name" : "ParameterList", - "src" : "49:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 11, - "name" : "ParameterList", - "src" : "64:0:1" - }, - { - "children" : - [ - { - "attributes" : - { - "argumentTypes" : null, - "overloadedDeclarations" : - [ - null - ], - "referencedDeclaration" : 6, - "type" : "modifier (uint256)", - "value" : "M" - }, - "id" : 8, - "name" : "Identifier", - "src" : "52:1:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "hexvalue" : "31", - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "subdenomination" : null, - "token" : "number", - "type" : "int_const 1", - "value" : "1" - }, - "id" : 9, - "name" : "Literal", - "src" : "54:1:1" - } - ], - "id" : 10, - "name" : "ModifierInvocation", - "src" : "52:4:1" - }, - { - "attributes" : - { - "statements" : - [ - null - ] - }, - "children" : [], - "id" : 12, - "name" : "Block", - "src" : "64:2:1" - } - ], - "id" : 13, - "name" : "FunctionDefinition", - "src" : "39:27:1" - } - ], - "id" : 14, - "name" : "ContractDefinition", - "src" : "0:68:1" - } - ], - "id" : 15, - "name" : "SourceUnit", - "src" : "0:69:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 14 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 14 + ], + "name": "C", + "scope": 15 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "name": "M", + "visibility": "internal" + }, + "children": + [ + { + "children": + [ + { + "attributes": + { + "constant": false, + "name": "i", + "overrides": null, + "scope": 6, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 1, + "name": "ElementaryTypeName", + "src": "24:4:1" + } + ], + "id": 2, + "name": "VariableDeclaration", + "src": "24:6:1" + } + ], + "id": 3, + "name": "ParameterList", + "src": "23:8:1" + }, + { + "children": + [ + { + "id": 4, + "name": "PlaceholderStatement", + "src": "34:1:1" + } + ], + "id": 5, + "name": "Block", + "src": "32:6:1" + } + ], + "id": 6, + "name": "ModifierDefinition", + "src": "13:25:1" + }, + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "name": "F", + "overrides": null, + "scope": 14, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 7, + "name": "ParameterList", + "src": "49:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 11, + "name": "ParameterList", + "src": "64:0:1" + }, + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 6, + "type": "modifier (uint256)", + "value": "M" + }, + "id": 8, + "name": "Identifier", + "src": "52:1:1" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "31", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 1", + "value": "1" + }, + "id": 9, + "name": "Literal", + "src": "54:1:1" + } + ], + "id": 10, + "name": "ModifierInvocation", + "src": "52:4:1" + }, + { + "attributes": + { + "statements": + [ + null + ] + }, + "children": [], + "id": 12, + "name": "Block", + "src": "64:2:1" + } + ], + "id": 13, + "name": "FunctionDefinition", + "src": "39:27:1" + } + ], + "id": 14, + "name": "ContractDefinition", + "src": "0:68:1" + } + ], + "id": 15, + "name": "SourceUnit", + "src": "0:69:1" } diff --git a/test/libsolidity/ASTJSON/modifier_invocation.json b/test/libsolidity/ASTJSON/modifier_invocation.json index 0e512e8049dd..89710117f685 100644 --- a/test/libsolidity/ASTJSON/modifier_invocation.json +++ b/test/libsolidity/ASTJSON/modifier_invocation.json @@ -1,176 +1,176 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 14 - ] - }, - "id" : 15, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 14, - "linearizedBaseContracts" : - [ - 14 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 5, - "nodeType" : "Block", - "src" : "32:6:1", - "statements" : - [ - { - "id" : 4, - "nodeType" : "PlaceholderStatement", - "src" : "34:1:1" - } - ] - }, - "documentation" : null, - "id" : 6, - "name" : "M", - "nodeType" : "ModifierDefinition", - "parameters" : - { - "id" : 3, - "nodeType" : "ParameterList", - "parameters" : - [ - { - "constant" : false, - "id" : 2, - "name" : "i", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 6, - "src" : "24:6:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - }, - "typeName" : - { - "id" : 1, - "name" : "uint", - "nodeType" : "ElementaryTypeName", - "src" : "24:4:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "src" : "23:8:1" - }, - "src" : "13:25:1", - "visibility" : "internal" - }, - { - "body" : - { - "id" : 12, - "nodeType" : "Block", - "src" : "64:2:1", - "statements" : [] - }, - "documentation" : null, - "id" : 13, - "implemented" : true, - "kind" : "function", - "modifiers" : - [ - { - "arguments" : - [ - { - "argumentTypes" : null, - "hexValue" : "31", - "id" : 9, - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "kind" : "number", - "lValueRequested" : false, - "nodeType" : "Literal", - "src" : "54:1:1", - "subdenomination" : null, - "typeDescriptions" : - { - "typeIdentifier" : "t_rational_1_by_1", - "typeString" : "int_const 1" - }, - "value" : "1" - } - ], - "id" : 10, - "modifierName" : - { - "argumentTypes" : null, - "id" : 8, - "name" : "M", - "nodeType" : "Identifier", - "overloadedDeclarations" : [], - "referencedDeclaration" : 6, - "src" : "52:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_modifier$_t_uint256_$", - "typeString" : "modifier (uint256)" - } - }, - "nodeType" : "ModifierInvocation", - "src" : "52:4:1" - } - ], - "name" : "F", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 7, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "49:2:1" - }, - "returnParameters" : - { - "id" : 11, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "64:0:1" - }, - "scope" : 14, - "src" : "39:27:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - } - ], - "scope" : 15, - "src" : "0:68:1" - } - ], - "src" : "0:69:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 14 + ] + }, + "id": 15, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 14, + "linearizedBaseContracts": + [ + 14 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 5, + "nodeType": "Block", + "src": "32:6:1", + "statements": + [ + { + "id": 4, + "nodeType": "PlaceholderStatement", + "src": "34:1:1" + } + ] + }, + "documentation": null, + "id": 6, + "name": "M", + "nodeType": "ModifierDefinition", + "parameters": + { + "id": 3, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2, + "name": "i", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 6, + "src": "24:6:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "24:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "value": null, + "visibility": "internal" + } + ], + "src": "23:8:1" + }, + "src": "13:25:1", + "visibility": "internal" + }, + { + "body": + { + "id": 12, + "nodeType": "Block", + "src": "64:2:1", + "statements": [] + }, + "documentation": null, + "id": 13, + "implemented": true, + "kind": "function", + "modifiers": + [ + { + "arguments": + [ + { + "argumentTypes": null, + "hexValue": "31", + "id": 9, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "54:1:1", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_1_by_1", + "typeString": "int_const 1" + }, + "value": "1" + } + ], + "id": 10, + "modifierName": + { + "argumentTypes": null, + "id": 8, + "name": "M", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 6, + "src": "52:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_modifier$_t_uint256_$", + "typeString": "modifier (uint256)" + } + }, + "nodeType": "ModifierInvocation", + "src": "52:4:1" + } + ], + "name": "F", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 7, + "nodeType": "ParameterList", + "parameters": [], + "src": "49:2:1" + }, + "returnParameters": + { + "id": 11, + "nodeType": "ParameterList", + "parameters": [], + "src": "64:0:1" + }, + "scope": 14, + "src": "39:27:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 15, + "src": "0:68:1" + } + ], + "src": "0:69:1" } diff --git a/test/libsolidity/ASTJSON/modifier_invocation_legacy.json b/test/libsolidity/ASTJSON/modifier_invocation_legacy.json index 5bb91624ebfe..c3574404dfe4 100644 --- a/test/libsolidity/ASTJSON/modifier_invocation_legacy.json +++ b/test/libsolidity/ASTJSON/modifier_invocation_legacy.json @@ -1,214 +1,214 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 14 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 14 - ], - "name" : "C", - "scope" : 15 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "name" : "M", - "visibility" : "internal" - }, - "children" : - [ - { - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "i", - "overrides" : null, - "scope" : 6, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "uint256", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "name" : "uint", - "type" : "uint256" - }, - "id" : 1, - "name" : "ElementaryTypeName", - "src" : "24:4:1" - } - ], - "id" : 2, - "name" : "VariableDeclaration", - "src" : "24:6:1" - } - ], - "id" : 3, - "name" : "ParameterList", - "src" : "23:8:1" - }, - { - "children" : - [ - { - "id" : 4, - "name" : "PlaceholderStatement", - "src" : "34:1:1" - } - ], - "id" : 5, - "name" : "Block", - "src" : "32:6:1" - } - ], - "id" : 6, - "name" : "ModifierDefinition", - "src" : "13:25:1" - }, - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "name" : "F", - "overrides" : null, - "scope" : 14, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 7, - "name" : "ParameterList", - "src" : "49:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 11, - "name" : "ParameterList", - "src" : "64:0:1" - }, - { - "children" : - [ - { - "attributes" : - { - "argumentTypes" : null, - "overloadedDeclarations" : - [ - null - ], - "referencedDeclaration" : 6, - "type" : "modifier (uint256)", - "value" : "M" - }, - "id" : 8, - "name" : "Identifier", - "src" : "52:1:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "hexvalue" : "31", - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "subdenomination" : null, - "token" : "number", - "type" : "int_const 1", - "value" : "1" - }, - "id" : 9, - "name" : "Literal", - "src" : "54:1:1" - } - ], - "id" : 10, - "name" : "ModifierInvocation", - "src" : "52:4:1" - }, - { - "attributes" : - { - "statements" : - [ - null - ] - }, - "children" : [], - "id" : 12, - "name" : "Block", - "src" : "64:2:1" - } - ], - "id" : 13, - "name" : "FunctionDefinition", - "src" : "39:27:1" - } - ], - "id" : 14, - "name" : "ContractDefinition", - "src" : "0:68:1" - } - ], - "id" : 15, - "name" : "SourceUnit", - "src" : "0:69:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 14 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 14 + ], + "name": "C", + "scope": 15 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "name": "M", + "visibility": "internal" + }, + "children": + [ + { + "children": + [ + { + "attributes": + { + "constant": false, + "name": "i", + "overrides": null, + "scope": 6, + "stateVariable": false, + "storageLocation": "default", + "type": "uint256", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 1, + "name": "ElementaryTypeName", + "src": "24:4:1" + } + ], + "id": 2, + "name": "VariableDeclaration", + "src": "24:6:1" + } + ], + "id": 3, + "name": "ParameterList", + "src": "23:8:1" + }, + { + "children": + [ + { + "id": 4, + "name": "PlaceholderStatement", + "src": "34:1:1" + } + ], + "id": 5, + "name": "Block", + "src": "32:6:1" + } + ], + "id": 6, + "name": "ModifierDefinition", + "src": "13:25:1" + }, + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "name": "F", + "overrides": null, + "scope": 14, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 7, + "name": "ParameterList", + "src": "49:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 11, + "name": "ParameterList", + "src": "64:0:1" + }, + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 6, + "type": "modifier (uint256)", + "value": "M" + }, + "id": 8, + "name": "Identifier", + "src": "52:1:1" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "31", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 1", + "value": "1" + }, + "id": 9, + "name": "Literal", + "src": "54:1:1" + } + ], + "id": 10, + "name": "ModifierInvocation", + "src": "52:4:1" + }, + { + "attributes": + { + "statements": + [ + null + ] + }, + "children": [], + "id": 12, + "name": "Block", + "src": "64:2:1" + } + ], + "id": 13, + "name": "FunctionDefinition", + "src": "39:27:1" + } + ], + "id": 14, + "name": "ContractDefinition", + "src": "0:68:1" + } + ], + "id": 15, + "name": "SourceUnit", + "src": "0:69:1" } diff --git a/test/libsolidity/ASTJSON/non_utf8.json b/test/libsolidity/ASTJSON/non_utf8.json index 99312bd46d12..ef744becaf11 100644 --- a/test/libsolidity/ASTJSON/non_utf8.json +++ b/test/libsolidity/ASTJSON/non_utf8.json @@ -1,124 +1,124 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 8 - ] - }, - "id" : 9, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 8, - "linearizedBaseContracts" : - [ - 8 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 6, - "nodeType" : "Block", - "src" : "33:20:1", - "statements" : - [ - { - "assignments" : - [ - 3 - ], - "declarations" : - [ - { - "constant" : false, - "id" : 3, - "name" : "x", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 6, - "src" : "35:5:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_string_memory_ptr", - "typeString" : "string" - }, - "typeName" : null, - "value" : null, - "visibility" : "internal" - } - ], - "id" : 5, - "initialValue" : - { - "argumentTypes" : null, - "hexValue" : "ff", - "id" : 4, - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "kind" : "string", - "lValueRequested" : false, - "nodeType" : "Literal", - "src" : "43:7:1", - "subdenomination" : null, - "typeDescriptions" : - { - "typeIdentifier" : "t_stringliteral_8b1a944cf13a9a1c08facb2c9e98623ef3254d2ddb48113885c3e8e97fec8db9", - "typeString" : "literal_string (contains invalid UTF-8 sequence at position 0)" - }, - "value" : null - }, - "nodeType" : "VariableDeclarationStatement", - "src" : "35:15:1" - } - ] - }, - "documentation" : null, - "id" : 7, - "implemented" : true, - "kind" : "function", - "modifiers" : [], - "name" : "f", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 1, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "23:2:1" - }, - "returnParameters" : - { - "id" : 2, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "33:0:1" - }, - "scope" : 8, - "src" : "13:40:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - } - ], - "scope" : 9, - "src" : "0:55:1" - } - ], - "src" : "0:56:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 8 + ] + }, + "id": 9, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 8, + "linearizedBaseContracts": + [ + 8 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 6, + "nodeType": "Block", + "src": "33:20:1", + "statements": + [ + { + "assignments": + [ + 3 + ], + "declarations": + [ + { + "constant": false, + "id": 3, + "name": "x", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 6, + "src": "35:5:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_string_memory_ptr", + "typeString": "string" + }, + "typeName": null, + "value": null, + "visibility": "internal" + } + ], + "id": 5, + "initialValue": + { + "argumentTypes": null, + "hexValue": "ff", + "id": 4, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "string", + "lValueRequested": false, + "nodeType": "Literal", + "src": "43:7:1", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_stringliteral_8b1a944cf13a9a1c08facb2c9e98623ef3254d2ddb48113885c3e8e97fec8db9", + "typeString": "literal_string (contains invalid UTF-8 sequence at position 0)" + }, + "value": null + }, + "nodeType": "VariableDeclarationStatement", + "src": "35:15:1" + } + ] + }, + "documentation": null, + "id": 7, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "33:0:1" + }, + "scope": 8, + "src": "13:40:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 9, + "src": "0:55:1" + } + ], + "src": "0:56:1" } diff --git a/test/libsolidity/ASTJSON/non_utf8_legacy.json b/test/libsolidity/ASTJSON/non_utf8_legacy.json index 5abbce9742d0..380b095d622d 100644 --- a/test/libsolidity/ASTJSON/non_utf8_legacy.json +++ b/test/libsolidity/ASTJSON/non_utf8_legacy.json @@ -1,158 +1,158 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 8 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 8 - ], - "name" : "C", - "scope" : 9 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "f", - "overrides" : null, - "scope" : 8, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 1, - "name" : "ParameterList", - "src" : "23:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 2, - "name" : "ParameterList", - "src" : "33:0:1" - }, - { - "children" : - [ - { - "attributes" : - { - "assignments" : - [ - 3 - ] - }, - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "x", - "overrides" : null, - "scope" : 6, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "string", - "typeName" : null, - "value" : null, - "visibility" : "internal" - }, - "children" : [], - "id" : 3, - "name" : "VariableDeclaration", - "src" : "35:5:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "hexvalue" : "ff", - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "subdenomination" : null, - "token" : "string", - "type" : "literal_string (contains invalid UTF-8 sequence at position 0)", - "value" : null - }, - "id" : 4, - "name" : "Literal", - "src" : "43:7:1" - } - ], - "id" : 5, - "name" : "VariableDeclarationStatement", - "src" : "35:15:1" - } - ], - "id" : 6, - "name" : "Block", - "src" : "33:20:1" - } - ], - "id" : 7, - "name" : "FunctionDefinition", - "src" : "13:40:1" - } - ], - "id" : 8, - "name" : "ContractDefinition", - "src" : "0:55:1" - } - ], - "id" : 9, - "name" : "SourceUnit", - "src" : "0:56:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 8 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 8 + ], + "name": "C", + "scope": 9 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "f", + "overrides": null, + "scope": 8, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 1, + "name": "ParameterList", + "src": "23:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 2, + "name": "ParameterList", + "src": "33:0:1" + }, + { + "children": + [ + { + "attributes": + { + "assignments": + [ + 3 + ] + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "x", + "overrides": null, + "scope": 6, + "stateVariable": false, + "storageLocation": "default", + "type": "string", + "typeName": null, + "value": null, + "visibility": "internal" + }, + "children": [], + "id": 3, + "name": "VariableDeclaration", + "src": "35:5:1" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "ff", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "string", + "type": "literal_string (contains invalid UTF-8 sequence at position 0)", + "value": null + }, + "id": 4, + "name": "Literal", + "src": "43:7:1" + } + ], + "id": 5, + "name": "VariableDeclarationStatement", + "src": "35:15:1" + } + ], + "id": 6, + "name": "Block", + "src": "33:20:1" + } + ], + "id": 7, + "name": "FunctionDefinition", + "src": "13:40:1" + } + ], + "id": 8, + "name": "ContractDefinition", + "src": "0:55:1" + } + ], + "id": 9, + "name": "SourceUnit", + "src": "0:56:1" } diff --git a/test/libsolidity/ASTJSON/override.json b/test/libsolidity/ASTJSON/override.json index 976ae7c1db15..a57bfcb61905 100644 --- a/test/libsolidity/ASTJSON/override.json +++ b/test/libsolidity/ASTJSON/override.json @@ -1,337 +1,337 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "A" : - [ - 5 - ], - "B" : - [ - 16 - ], - "C" : - [ - 31 - ] - }, - "id" : 32, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 5, - "linearizedBaseContracts" : - [ - 5 - ], - "name" : "A", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 3, - "nodeType" : "Block", - "src" : "36:2:1", - "statements" : [] - }, - "documentation" : null, - "id" : 4, - "implemented" : true, - "kind" : "function", - "modifiers" : [], - "name" : "faa", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 1, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "26:2:1" - }, - "returnParameters" : - { - "id" : 2, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "36:0:1" - }, - "scope" : 5, - "src" : "14:24:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - } - ], - "scope" : 32, - "src" : "0:40:1" - }, - { - "baseContracts" : - [ - { - "arguments" : null, - "baseName" : - { - "contractScope" : null, - "id" : 6, - "name" : "A", - "nodeType" : "UserDefinedTypeName", - "referencedDeclaration" : 5, - "src" : "55:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_contract$_A_$5", - "typeString" : "contract A" - } - }, - "id" : 7, - "nodeType" : "InheritanceSpecifier", - "src" : "55:1:1" - } - ], - "contractDependencies" : - [ - 5 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : false, - "id" : 16, - "linearizedBaseContracts" : - [ - 16, - 5 - ], - "name" : "B", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : null, - "documentation" : null, - "id" : 10, - "implemented" : false, - "kind" : "function", - "modifiers" : [], - "name" : "foo", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 8, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "72:2:1" - }, - "returnParameters" : - { - "id" : 9, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "81:0:1" - }, - "scope" : 16, - "src" : "60:22:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - { - "body" : - { - "id" : 14, - "nodeType" : "Block", - "src" : "115:2:1", - "statements" : [] - }, - "documentation" : null, - "id" : 15, - "implemented" : true, - "kind" : "function", - "modifiers" : [], - "name" : "faa", - "nodeType" : "FunctionDefinition", - "overrides" : [], - "parameters" : - { - "id" : 11, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "96:2:1" - }, - "returnParameters" : - { - "id" : 13, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "115:0:1" - }, - "scope" : 16, - "src" : "84:33:1", - "stateMutability" : "nonpayable", - "superFunction" : 4, - "visibility" : "public" - } - ], - "scope" : 32, - "src" : "41:78:1" - }, - { - "baseContracts" : - [ - { - "arguments" : null, - "baseName" : - { - "contractScope" : null, - "id" : 17, - "name" : "B", - "nodeType" : "UserDefinedTypeName", - "referencedDeclaration" : 16, - "src" : "134:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_contract$_B_$16", - "typeString" : "contract B" - } - }, - "id" : 18, - "nodeType" : "InheritanceSpecifier", - "src" : "134:1:1" - } - ], - "contractDependencies" : - [ - 5, - 16 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 31, - "linearizedBaseContracts" : - [ - 31, - 16, - 5 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 22, - "nodeType" : "Block", - "src" : "170:3:1", - "statements" : [] - }, - "documentation" : null, - "id" : 23, - "implemented" : true, - "kind" : "function", - "modifiers" : [], - "name" : "foo", - "nodeType" : "FunctionDefinition", - "overrides" : [], - "parameters" : - { - "id" : 19, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "151:2:1" - }, - "returnParameters" : - { - "id" : 21, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "170:0:1" - }, - "scope" : 31, - "src" : "139:34:1", - "stateMutability" : "nonpayable", - "superFunction" : 10, - "visibility" : "public" - }, - { - "body" : - { - "id" : 29, - "nodeType" : "Block", - "src" : "212:2:1", - "statements" : [] - }, - "documentation" : null, - "id" : 30, - "implemented" : true, - "kind" : "function", - "modifiers" : [], - "name" : "faa", - "nodeType" : "FunctionDefinition", - "overrides" : - [ - { - "contractScope" : null, - "id" : 25, - "name" : "A", - "nodeType" : "UserDefinedTypeName", - "referencedDeclaration" : 5, - "src" : "206:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_contract$_A_$5", - "typeString" : "contract A" - } - }, - { - "contractScope" : null, - "id" : 26, - "name" : "B", - "nodeType" : "UserDefinedTypeName", - "referencedDeclaration" : 16, - "src" : "209:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_contract$_B_$16", - "typeString" : "contract B" - } - } - ], - "parameters" : - { - "id" : 24, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "187:2:1" - }, - "returnParameters" : - { - "id" : 28, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "212:0:1" - }, - "scope" : 31, - "src" : "175:39:1", - "stateMutability" : "nonpayable", - "superFunction" : 15, - "visibility" : "public" - } - ], - "scope" : 32, - "src" : "120:96:1" - } - ], - "src" : "0:217:1" + "absolutePath": "a", + "exportedSymbols": + { + "A": + [ + 5 + ], + "B": + [ + 16 + ], + "C": + [ + 31 + ] + }, + "id": 32, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "A", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "36:2:1", + "statements": [] + }, + "documentation": null, + "id": 4, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "faa", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "26:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "36:0:1" + }, + "scope": 5, + "src": "14:24:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 32, + "src": "0:40:1" + }, + { + "baseContracts": + [ + { + "arguments": null, + "baseName": + { + "contractScope": null, + "id": 6, + "name": "A", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 5, + "src": "55:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_A_$5", + "typeString": "contract A" + } + }, + "id": 7, + "nodeType": "InheritanceSpecifier", + "src": "55:1:1" + } + ], + "contractDependencies": + [ + 5 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": false, + "id": 16, + "linearizedBaseContracts": + [ + 16, + 5 + ], + "name": "B", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": null, + "documentation": null, + "id": 10, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "foo", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 8, + "nodeType": "ParameterList", + "parameters": [], + "src": "72:2:1" + }, + "returnParameters": + { + "id": 9, + "nodeType": "ParameterList", + "parameters": [], + "src": "81:0:1" + }, + "scope": 16, + "src": "60:22:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + { + "body": + { + "id": 14, + "nodeType": "Block", + "src": "115:2:1", + "statements": [] + }, + "documentation": null, + "id": 15, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "faa", + "nodeType": "FunctionDefinition", + "overrides": [], + "parameters": + { + "id": 11, + "nodeType": "ParameterList", + "parameters": [], + "src": "96:2:1" + }, + "returnParameters": + { + "id": 13, + "nodeType": "ParameterList", + "parameters": [], + "src": "115:0:1" + }, + "scope": 16, + "src": "84:33:1", + "stateMutability": "nonpayable", + "superFunction": 4, + "visibility": "public" + } + ], + "scope": 32, + "src": "41:78:1" + }, + { + "baseContracts": + [ + { + "arguments": null, + "baseName": + { + "contractScope": null, + "id": 17, + "name": "B", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 16, + "src": "134:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_B_$16", + "typeString": "contract B" + } + }, + "id": 18, + "nodeType": "InheritanceSpecifier", + "src": "134:1:1" + } + ], + "contractDependencies": + [ + 5, + 16 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 31, + "linearizedBaseContracts": + [ + 31, + 16, + 5 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 22, + "nodeType": "Block", + "src": "170:3:1", + "statements": [] + }, + "documentation": null, + "id": 23, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "foo", + "nodeType": "FunctionDefinition", + "overrides": [], + "parameters": + { + "id": 19, + "nodeType": "ParameterList", + "parameters": [], + "src": "151:2:1" + }, + "returnParameters": + { + "id": 21, + "nodeType": "ParameterList", + "parameters": [], + "src": "170:0:1" + }, + "scope": 31, + "src": "139:34:1", + "stateMutability": "nonpayable", + "superFunction": 10, + "visibility": "public" + }, + { + "body": + { + "id": 29, + "nodeType": "Block", + "src": "212:2:1", + "statements": [] + }, + "documentation": null, + "id": 30, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "faa", + "nodeType": "FunctionDefinition", + "overrides": + [ + { + "contractScope": null, + "id": 25, + "name": "A", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 5, + "src": "206:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_A_$5", + "typeString": "contract A" + } + }, + { + "contractScope": null, + "id": 26, + "name": "B", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 16, + "src": "209:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_B_$16", + "typeString": "contract B" + } + } + ], + "parameters": + { + "id": 24, + "nodeType": "ParameterList", + "parameters": [], + "src": "187:2:1" + }, + "returnParameters": + { + "id": 28, + "nodeType": "ParameterList", + "parameters": [], + "src": "212:0:1" + }, + "scope": 31, + "src": "175:39:1", + "stateMutability": "nonpayable", + "superFunction": 15, + "visibility": "public" + } + ], + "scope": 32, + "src": "120:96:1" + } + ], + "src": "0:217:1" } diff --git a/test/libsolidity/ASTJSON/override_legacy.json b/test/libsolidity/ASTJSON/override_legacy.json index d7ef04356584..c62a057c94e1 100644 --- a/test/libsolidity/ASTJSON/override_legacy.json +++ b/test/libsolidity/ASTJSON/override_legacy.json @@ -1,492 +1,492 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "A" : - [ - 5 - ], - "B" : - [ - 16 - ], - "C" : - [ - 31 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 5 - ], - "name" : "A", - "scope" : 32 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "faa", - "overrides" : null, - "scope" : 5, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 1, - "name" : "ParameterList", - "src" : "26:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 2, - "name" : "ParameterList", - "src" : "36:0:1" - }, - { - "attributes" : - { - "statements" : - [ - null - ] - }, - "children" : [], - "id" : 3, - "name" : "Block", - "src" : "36:2:1" - } - ], - "id" : 4, - "name" : "FunctionDefinition", - "src" : "14:24:1" - } - ], - "id" : 5, - "name" : "ContractDefinition", - "src" : "0:40:1" - }, - { - "attributes" : - { - "contractDependencies" : - [ - 5 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : false, - "linearizedBaseContracts" : - [ - 16, - 5 - ], - "name" : "B", - "scope" : 32 - }, - "children" : - [ - { - "attributes" : - { - "arguments" : null - }, - "children" : - [ - { - "attributes" : - { - "contractScope" : null, - "name" : "A", - "referencedDeclaration" : 5, - "type" : "contract A" - }, - "id" : 6, - "name" : "UserDefinedTypeName", - "src" : "55:1:1" - } - ], - "id" : 7, - "name" : "InheritanceSpecifier", - "src" : "55:1:1" - }, - { - "attributes" : - { - "body" : null, - "documentation" : null, - "implemented" : false, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "foo", - "overrides" : null, - "scope" : 16, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 8, - "name" : "ParameterList", - "src" : "72:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 9, - "name" : "ParameterList", - "src" : "81:0:1" - } - ], - "id" : 10, - "name" : "FunctionDefinition", - "src" : "60:22:1" - }, - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "faa", - "overrides" : - [ - null - ], - "scope" : 16, - "stateMutability" : "nonpayable", - "superFunction" : 4, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 11, - "name" : "ParameterList", - "src" : "96:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 13, - "name" : "ParameterList", - "src" : "115:0:1" - }, - { - "attributes" : - { - "statements" : - [ - null - ] - }, - "children" : [], - "id" : 14, - "name" : "Block", - "src" : "115:2:1" - } - ], - "id" : 15, - "name" : "FunctionDefinition", - "src" : "84:33:1" - } - ], - "id" : 16, - "name" : "ContractDefinition", - "src" : "41:78:1" - }, - { - "attributes" : - { - "contractDependencies" : - [ - 5, - 16 - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 31, - 16, - 5 - ], - "name" : "C", - "scope" : 32 - }, - "children" : - [ - { - "attributes" : - { - "arguments" : null - }, - "children" : - [ - { - "attributes" : - { - "contractScope" : null, - "name" : "B", - "referencedDeclaration" : 16, - "type" : "contract B" - }, - "id" : 17, - "name" : "UserDefinedTypeName", - "src" : "134:1:1" - } - ], - "id" : 18, - "name" : "InheritanceSpecifier", - "src" : "134:1:1" - }, - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "foo", - "overrides" : - [ - null - ], - "scope" : 31, - "stateMutability" : "nonpayable", - "superFunction" : 10, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 19, - "name" : "ParameterList", - "src" : "151:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 21, - "name" : "ParameterList", - "src" : "170:0:1" - }, - { - "attributes" : - { - "statements" : - [ - null - ] - }, - "children" : [], - "id" : 22, - "name" : "Block", - "src" : "170:3:1" - } - ], - "id" : 23, - "name" : "FunctionDefinition", - "src" : "139:34:1" - }, - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "faa", - "scope" : 31, - "stateMutability" : "nonpayable", - "superFunction" : 15, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "contractScope" : null, - "name" : "A", - "referencedDeclaration" : 5, - "type" : "contract A" - }, - "id" : 25, - "name" : "UserDefinedTypeName", - "src" : "206:1:1" - }, - { - "attributes" : - { - "contractScope" : null, - "name" : "B", - "referencedDeclaration" : 16, - "type" : "contract B" - }, - "id" : 26, - "name" : "UserDefinedTypeName", - "src" : "209:1:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 24, - "name" : "ParameterList", - "src" : "187:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 28, - "name" : "ParameterList", - "src" : "212:0:1" - }, - { - "attributes" : - { - "statements" : - [ - null - ] - }, - "children" : [], - "id" : 29, - "name" : "Block", - "src" : "212:2:1" - } - ], - "id" : 30, - "name" : "FunctionDefinition", - "src" : "175:39:1" - } - ], - "id" : 31, - "name" : "ContractDefinition", - "src" : "120:96:1" - } - ], - "id" : 32, - "name" : "SourceUnit", - "src" : "0:217:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "A": + [ + 5 + ], + "B": + [ + 16 + ], + "C": + [ + 31 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 5 + ], + "name": "A", + "scope": 32 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "faa", + "overrides": null, + "scope": 5, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 1, + "name": "ParameterList", + "src": "26:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 2, + "name": "ParameterList", + "src": "36:0:1" + }, + { + "attributes": + { + "statements": + [ + null + ] + }, + "children": [], + "id": 3, + "name": "Block", + "src": "36:2:1" + } + ], + "id": 4, + "name": "FunctionDefinition", + "src": "14:24:1" + } + ], + "id": 5, + "name": "ContractDefinition", + "src": "0:40:1" + }, + { + "attributes": + { + "contractDependencies": + [ + 5 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": false, + "linearizedBaseContracts": + [ + 16, + 5 + ], + "name": "B", + "scope": 32 + }, + "children": + [ + { + "attributes": + { + "arguments": null + }, + "children": + [ + { + "attributes": + { + "contractScope": null, + "name": "A", + "referencedDeclaration": 5, + "type": "contract A" + }, + "id": 6, + "name": "UserDefinedTypeName", + "src": "55:1:1" + } + ], + "id": 7, + "name": "InheritanceSpecifier", + "src": "55:1:1" + }, + { + "attributes": + { + "body": null, + "documentation": null, + "implemented": false, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "foo", + "overrides": null, + "scope": 16, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 8, + "name": "ParameterList", + "src": "72:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 9, + "name": "ParameterList", + "src": "81:0:1" + } + ], + "id": 10, + "name": "FunctionDefinition", + "src": "60:22:1" + }, + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "faa", + "overrides": + [ + null + ], + "scope": 16, + "stateMutability": "nonpayable", + "superFunction": 4, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 11, + "name": "ParameterList", + "src": "96:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 13, + "name": "ParameterList", + "src": "115:0:1" + }, + { + "attributes": + { + "statements": + [ + null + ] + }, + "children": [], + "id": 14, + "name": "Block", + "src": "115:2:1" + } + ], + "id": 15, + "name": "FunctionDefinition", + "src": "84:33:1" + } + ], + "id": 16, + "name": "ContractDefinition", + "src": "41:78:1" + }, + { + "attributes": + { + "contractDependencies": + [ + 5, + 16 + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 31, + 16, + 5 + ], + "name": "C", + "scope": 32 + }, + "children": + [ + { + "attributes": + { + "arguments": null + }, + "children": + [ + { + "attributes": + { + "contractScope": null, + "name": "B", + "referencedDeclaration": 16, + "type": "contract B" + }, + "id": 17, + "name": "UserDefinedTypeName", + "src": "134:1:1" + } + ], + "id": 18, + "name": "InheritanceSpecifier", + "src": "134:1:1" + }, + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "foo", + "overrides": + [ + null + ], + "scope": 31, + "stateMutability": "nonpayable", + "superFunction": 10, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 19, + "name": "ParameterList", + "src": "151:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 21, + "name": "ParameterList", + "src": "170:0:1" + }, + { + "attributes": + { + "statements": + [ + null + ] + }, + "children": [], + "id": 22, + "name": "Block", + "src": "170:3:1" + } + ], + "id": 23, + "name": "FunctionDefinition", + "src": "139:34:1" + }, + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "faa", + "scope": 31, + "stateMutability": "nonpayable", + "superFunction": 15, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "contractScope": null, + "name": "A", + "referencedDeclaration": 5, + "type": "contract A" + }, + "id": 25, + "name": "UserDefinedTypeName", + "src": "206:1:1" + }, + { + "attributes": + { + "contractScope": null, + "name": "B", + "referencedDeclaration": 16, + "type": "contract B" + }, + "id": 26, + "name": "UserDefinedTypeName", + "src": "209:1:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 24, + "name": "ParameterList", + "src": "187:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 28, + "name": "ParameterList", + "src": "212:0:1" + }, + { + "attributes": + { + "statements": + [ + null + ] + }, + "children": [], + "id": 29, + "name": "Block", + "src": "212:2:1" + } + ], + "id": 30, + "name": "FunctionDefinition", + "src": "175:39:1" + } + ], + "id": 31, + "name": "ContractDefinition", + "src": "120:96:1" + } + ], + "id": 32, + "name": "SourceUnit", + "src": "0:217:1" } diff --git a/test/libsolidity/ASTJSON/placeholder_statement.json b/test/libsolidity/ASTJSON/placeholder_statement.json index 496e15001e88..1a7b005dca54 100644 --- a/test/libsolidity/ASTJSON/placeholder_statement.json +++ b/test/libsolidity/ASTJSON/placeholder_statement.json @@ -1,64 +1,64 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 5 - ] - }, - "id" : 6, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 5, - "linearizedBaseContracts" : - [ - 5 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 3, - "nodeType" : "Block", - "src" : "24:6:1", - "statements" : - [ - { - "id" : 2, - "nodeType" : "PlaceholderStatement", - "src" : "26:1:1" - } - ] - }, - "documentation" : null, - "id" : 4, - "name" : "M", - "nodeType" : "ModifierDefinition", - "parameters" : - { - "id" : 1, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "24:0:1" - }, - "src" : "13:17:1", - "visibility" : "internal" - } - ], - "scope" : 6, - "src" : "0:32:1" - } - ], - "src" : "0:33:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + }, + "id": 6, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 3, + "nodeType": "Block", + "src": "24:6:1", + "statements": + [ + { + "id": 2, + "nodeType": "PlaceholderStatement", + "src": "26:1:1" + } + ] + }, + "documentation": null, + "id": 4, + "name": "M", + "nodeType": "ModifierDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "24:0:1" + }, + "src": "13:17:1", + "visibility": "internal" + } + ], + "scope": 6, + "src": "0:32:1" + } + ], + "src": "0:33:1" } diff --git a/test/libsolidity/ASTJSON/placeholder_statement_legacy.json b/test/libsolidity/ASTJSON/placeholder_statement_legacy.json index a558297622d0..8b79618f29e0 100644 --- a/test/libsolidity/ASTJSON/placeholder_statement_legacy.json +++ b/test/libsolidity/ASTJSON/placeholder_statement_legacy.json @@ -1,87 +1,87 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 5 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 5 - ], - "name" : "C", - "scope" : 6 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "name" : "M", - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 1, - "name" : "ParameterList", - "src" : "24:0:1" - }, - { - "children" : - [ - { - "id" : 2, - "name" : "PlaceholderStatement", - "src" : "26:1:1" - } - ], - "id" : 3, - "name" : "Block", - "src" : "24:6:1" - } - ], - "id" : 4, - "name" : "ModifierDefinition", - "src" : "13:17:1" - } - ], - "id" : 5, - "name" : "ContractDefinition", - "src" : "0:32:1" - } - ], - "id" : 6, - "name" : "SourceUnit", - "src" : "0:33:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "scope": 6 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "name": "M", + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 1, + "name": "ParameterList", + "src": "24:0:1" + }, + { + "children": + [ + { + "id": 2, + "name": "PlaceholderStatement", + "src": "26:1:1" + } + ], + "id": 3, + "name": "Block", + "src": "24:6:1" + } + ], + "id": 4, + "name": "ModifierDefinition", + "src": "13:17:1" + } + ], + "id": 5, + "name": "ContractDefinition", + "src": "0:32:1" + } + ], + "id": 6, + "name": "SourceUnit", + "src": "0:33:1" } diff --git a/test/libsolidity/ASTJSON/short_type_name.json b/test/libsolidity/ASTJSON/short_type_name.json index d599be955d67..635a91631492 100644 --- a/test/libsolidity/ASTJSON/short_type_name.json +++ b/test/libsolidity/ASTJSON/short_type_name.json @@ -1,128 +1,128 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "c" : - [ - 11 - ] - }, - "id" : 12, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 11, - "linearizedBaseContracts" : - [ - 11 - ], - "name" : "c", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 9, - "nodeType" : "Block", - "src" : "33:20:1", - "statements" : - [ - { - "assignments" : - [ - 7 - ], - "declarations" : - [ - { - "constant" : false, - "id" : 7, - "name" : "x", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 9, - "src" : "35:15:1", - "stateVariable" : false, - "storageLocation" : "memory", - "typeDescriptions" : - { - "typeIdentifier" : "t_array$_t_uint256_$dyn_memory_ptr", - "typeString" : "uint256[]" - }, - "typeName" : - { - "baseType" : - { - "id" : 5, - "name" : "uint", - "nodeType" : "ElementaryTypeName", - "src" : "35:4:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - } - }, - "id" : 6, - "length" : null, - "nodeType" : "ArrayTypeName", - "src" : "35:6:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_array$_t_uint256_$dyn_storage_ptr", - "typeString" : "uint256[]" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "id" : 8, - "initialValue" : null, - "nodeType" : "VariableDeclarationStatement", - "src" : "35:15:1" - } - ] - }, - "documentation" : null, - "id" : 10, - "implemented" : true, - "kind" : "function", - "modifiers" : [], - "name" : "f", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 1, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "23:2:1" - }, - "returnParameters" : - { - "id" : 2, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "33:0:1" - }, - "scope" : 11, - "src" : "13:40:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - } - ], - "scope" : 12, - "src" : "0:55:1" - } - ], - "src" : "0:56:1" + "absolutePath": "a", + "exportedSymbols": + { + "c": + [ + 11 + ] + }, + "id": 12, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 11, + "linearizedBaseContracts": + [ + 11 + ], + "name": "c", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 9, + "nodeType": "Block", + "src": "33:20:1", + "statements": + [ + { + "assignments": + [ + 7 + ], + "declarations": + [ + { + "constant": false, + "id": 7, + "name": "x", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 9, + "src": "35:15:1", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_memory_ptr", + "typeString": "uint256[]" + }, + "typeName": + { + "baseType": + { + "id": 5, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "35:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 6, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 8, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "35:15:1" + } + ] + }, + "documentation": null, + "id": 10, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "33:0:1" + }, + "scope": 11, + "src": "13:40:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 12, + "src": "0:55:1" + } + ], + "src": "0:56:1" } diff --git a/test/libsolidity/ASTJSON/short_type_name_legacy.json b/test/libsolidity/ASTJSON/short_type_name_legacy.json index 92d0abc306ad..c9389b292d19 100644 --- a/test/libsolidity/ASTJSON/short_type_name_legacy.json +++ b/test/libsolidity/ASTJSON/short_type_name_legacy.json @@ -1,165 +1,165 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "c" : - [ - 11 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 11 - ], - "name" : "c", - "scope" : 12 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "f", - "overrides" : null, - "scope" : 11, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 1, - "name" : "ParameterList", - "src" : "23:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 2, - "name" : "ParameterList", - "src" : "33:0:1" - }, - { - "children" : - [ - { - "attributes" : - { - "assignments" : - [ - 7 - ], - "initialValue" : null - }, - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "x", - "overrides" : null, - "scope" : 9, - "stateVariable" : false, - "storageLocation" : "memory", - "type" : "uint256[]", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "length" : null, - "type" : "uint256[]" - }, - "children" : - [ - { - "attributes" : - { - "name" : "uint", - "type" : "uint256" - }, - "id" : 5, - "name" : "ElementaryTypeName", - "src" : "35:4:1" - } - ], - "id" : 6, - "name" : "ArrayTypeName", - "src" : "35:6:1" - } - ], - "id" : 7, - "name" : "VariableDeclaration", - "src" : "35:15:1" - } - ], - "id" : 8, - "name" : "VariableDeclarationStatement", - "src" : "35:15:1" - } - ], - "id" : 9, - "name" : "Block", - "src" : "33:20:1" - } - ], - "id" : 10, - "name" : "FunctionDefinition", - "src" : "13:40:1" - } - ], - "id" : 11, - "name" : "ContractDefinition", - "src" : "0:55:1" - } - ], - "id" : 12, - "name" : "SourceUnit", - "src" : "0:56:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "c": + [ + 11 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 11 + ], + "name": "c", + "scope": 12 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "f", + "overrides": null, + "scope": 11, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 1, + "name": "ParameterList", + "src": "23:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 2, + "name": "ParameterList", + "src": "33:0:1" + }, + { + "children": + [ + { + "attributes": + { + "assignments": + [ + 7 + ], + "initialValue": null + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "x", + "overrides": null, + "scope": 9, + "stateVariable": false, + "storageLocation": "memory", + "type": "uint256[]", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "length": null, + "type": "uint256[]" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 5, + "name": "ElementaryTypeName", + "src": "35:4:1" + } + ], + "id": 6, + "name": "ArrayTypeName", + "src": "35:6:1" + } + ], + "id": 7, + "name": "VariableDeclaration", + "src": "35:15:1" + } + ], + "id": 8, + "name": "VariableDeclarationStatement", + "src": "35:15:1" + } + ], + "id": 9, + "name": "Block", + "src": "33:20:1" + } + ], + "id": 10, + "name": "FunctionDefinition", + "src": "13:40:1" + } + ], + "id": 11, + "name": "ContractDefinition", + "src": "0:55:1" + } + ], + "id": 12, + "name": "SourceUnit", + "src": "0:56:1" } diff --git a/test/libsolidity/ASTJSON/short_type_name_ref.json b/test/libsolidity/ASTJSON/short_type_name_ref.json index 51a13102fa5e..cf91bea9cca3 100644 --- a/test/libsolidity/ASTJSON/short_type_name_ref.json +++ b/test/libsolidity/ASTJSON/short_type_name_ref.json @@ -1,140 +1,140 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "c" : - [ - 12 - ] - }, - "id" : 13, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 12, - "linearizedBaseContracts" : - [ - 12 - ], - "name" : "c", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 10, - "nodeType" : "Block", - "src" : "33:25:1", - "statements" : - [ - { - "assignments" : - [ - 8 - ], - "declarations" : - [ - { - "constant" : false, - "id" : 8, - "name" : "rows", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 10, - "src" : "35:20:1", - "stateVariable" : false, - "storageLocation" : "memory", - "typeDescriptions" : - { - "typeIdentifier" : "t_array$_t_array$_t_uint256_$dyn_memory_$dyn_memory_ptr", - "typeString" : "uint256[][]" - }, - "typeName" : - { - "baseType" : - { - "baseType" : - { - "id" : 5, - "name" : "uint", - "nodeType" : "ElementaryTypeName", - "src" : "35:4:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - } - }, - "id" : 6, - "length" : null, - "nodeType" : "ArrayTypeName", - "src" : "35:6:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_array$_t_uint256_$dyn_storage_ptr", - "typeString" : "uint256[]" - } - }, - "id" : 7, - "length" : null, - "nodeType" : "ArrayTypeName", - "src" : "35:8:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_array$_t_array$_t_uint256_$dyn_storage_$dyn_storage_ptr", - "typeString" : "uint256[][]" - } - }, - "value" : null, - "visibility" : "internal" - } - ], - "id" : 9, - "initialValue" : null, - "nodeType" : "VariableDeclarationStatement", - "src" : "35:20:1" - } - ] - }, - "documentation" : null, - "id" : 11, - "implemented" : true, - "kind" : "function", - "modifiers" : [], - "name" : "f", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 1, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "23:2:1" - }, - "returnParameters" : - { - "id" : 2, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "33:0:1" - }, - "scope" : 12, - "src" : "13:45:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - } - ], - "scope" : 13, - "src" : "0:60:1" - } - ], - "src" : "0:61:1" + "absolutePath": "a", + "exportedSymbols": + { + "c": + [ + 12 + ] + }, + "id": 13, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 12, + "linearizedBaseContracts": + [ + 12 + ], + "name": "c", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 10, + "nodeType": "Block", + "src": "33:25:1", + "statements": + [ + { + "assignments": + [ + 8 + ], + "declarations": + [ + { + "constant": false, + "id": 8, + "name": "rows", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 10, + "src": "35:20:1", + "stateVariable": false, + "storageLocation": "memory", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_array$_t_uint256_$dyn_memory_$dyn_memory_ptr", + "typeString": "uint256[][]" + }, + "typeName": + { + "baseType": + { + "baseType": + { + "id": 5, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "35:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "id": 6, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35:6:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_uint256_$dyn_storage_ptr", + "typeString": "uint256[]" + } + }, + "id": 7, + "length": null, + "nodeType": "ArrayTypeName", + "src": "35:8:1", + "typeDescriptions": + { + "typeIdentifier": "t_array$_t_array$_t_uint256_$dyn_storage_$dyn_storage_ptr", + "typeString": "uint256[][]" + } + }, + "value": null, + "visibility": "internal" + } + ], + "id": 9, + "initialValue": null, + "nodeType": "VariableDeclarationStatement", + "src": "35:20:1" + } + ] + }, + "documentation": null, + "id": 11, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "33:0:1" + }, + "scope": 12, + "src": "13:45:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 13, + "src": "0:60:1" + } + ], + "src": "0:61:1" } diff --git a/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json b/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json index 99b4d550ebb7..b885ded3c504 100644 --- a/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json +++ b/test/libsolidity/ASTJSON/short_type_name_ref_legacy.json @@ -1,178 +1,178 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "c" : - [ - 12 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 12 - ], - "name" : "c", - "scope" : 13 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "f", - "overrides" : null, - "scope" : 12, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 1, - "name" : "ParameterList", - "src" : "23:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 2, - "name" : "ParameterList", - "src" : "33:0:1" - }, - { - "children" : - [ - { - "attributes" : - { - "assignments" : - [ - 8 - ], - "initialValue" : null - }, - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "rows", - "overrides" : null, - "scope" : 10, - "stateVariable" : false, - "storageLocation" : "memory", - "type" : "uint256[][]", - "value" : null, - "visibility" : "internal" - }, - "children" : - [ - { - "attributes" : - { - "length" : null, - "type" : "uint256[][]" - }, - "children" : - [ - { - "attributes" : - { - "length" : null, - "type" : "uint256[]" - }, - "children" : - [ - { - "attributes" : - { - "name" : "uint", - "type" : "uint256" - }, - "id" : 5, - "name" : "ElementaryTypeName", - "src" : "35:4:1" - } - ], - "id" : 6, - "name" : "ArrayTypeName", - "src" : "35:6:1" - } - ], - "id" : 7, - "name" : "ArrayTypeName", - "src" : "35:8:1" - } - ], - "id" : 8, - "name" : "VariableDeclaration", - "src" : "35:20:1" - } - ], - "id" : 9, - "name" : "VariableDeclarationStatement", - "src" : "35:20:1" - } - ], - "id" : 10, - "name" : "Block", - "src" : "33:25:1" - } - ], - "id" : 11, - "name" : "FunctionDefinition", - "src" : "13:45:1" - } - ], - "id" : 12, - "name" : "ContractDefinition", - "src" : "0:60:1" - } - ], - "id" : 13, - "name" : "SourceUnit", - "src" : "0:61:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "c": + [ + 12 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 12 + ], + "name": "c", + "scope": 13 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "f", + "overrides": null, + "scope": 12, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 1, + "name": "ParameterList", + "src": "23:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 2, + "name": "ParameterList", + "src": "33:0:1" + }, + { + "children": + [ + { + "attributes": + { + "assignments": + [ + 8 + ], + "initialValue": null + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "rows", + "overrides": null, + "scope": 10, + "stateVariable": false, + "storageLocation": "memory", + "type": "uint256[][]", + "value": null, + "visibility": "internal" + }, + "children": + [ + { + "attributes": + { + "length": null, + "type": "uint256[][]" + }, + "children": + [ + { + "attributes": + { + "length": null, + "type": "uint256[]" + }, + "children": + [ + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 5, + "name": "ElementaryTypeName", + "src": "35:4:1" + } + ], + "id": 6, + "name": "ArrayTypeName", + "src": "35:6:1" + } + ], + "id": 7, + "name": "ArrayTypeName", + "src": "35:8:1" + } + ], + "id": 8, + "name": "VariableDeclaration", + "src": "35:20:1" + } + ], + "id": 9, + "name": "VariableDeclarationStatement", + "src": "35:20:1" + } + ], + "id": 10, + "name": "Block", + "src": "33:25:1" + } + ], + "id": 11, + "name": "FunctionDefinition", + "src": "13:45:1" + } + ], + "id": 12, + "name": "ContractDefinition", + "src": "0:60:1" + } + ], + "id": 13, + "name": "SourceUnit", + "src": "0:61:1" } diff --git a/test/libsolidity/ASTJSON/smoke.json b/test/libsolidity/ASTJSON/smoke.json index f5369bfc8794..039ad3750328 100644 --- a/test/libsolidity/ASTJSON/smoke.json +++ b/test/libsolidity/ASTJSON/smoke.json @@ -1,33 +1,33 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 1 - ] - }, - "id" : 2, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 1, - "linearizedBaseContracts" : - [ - 1 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : [], - "scope" : 2, - "src" : "0:13:1" - } - ], - "src" : "0:14:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 1 + ] + }, + "id": 2, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 1, + "linearizedBaseContracts": + [ + 1 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 2, + "src": "0:13:1" + } + ], + "src": "0:14:1" } diff --git a/test/libsolidity/ASTJSON/smoke_legacy.json b/test/libsolidity/ASTJSON/smoke_legacy.json index e01a3c9b269b..0cb99ef43221 100644 --- a/test/libsolidity/ASTJSON/smoke_legacy.json +++ b/test/libsolidity/ASTJSON/smoke_legacy.json @@ -1,48 +1,48 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 1 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 1 - ], - "name" : "C", - "nodes" : - [ - null - ], - "scope" : 2 - }, - "id" : 1, - "name" : "ContractDefinition", - "src" : "0:13:1" - } - ], - "id" : 2, - "name" : "SourceUnit", - "src" : "0:14:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 1 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 1 + ], + "name": "C", + "nodes": + [ + null + ], + "scope": 2 + }, + "id": 1, + "name": "ContractDefinition", + "src": "0:13:1" + } + ], + "id": 2, + "name": "SourceUnit", + "src": "0:14:1" } diff --git a/test/libsolidity/ASTJSON/source_location.json b/test/libsolidity/ASTJSON/source_location.json index 0a3c9ccd6d46..d776dd134447 100644 --- a/test/libsolidity/ASTJSON/source_location.json +++ b/test/libsolidity/ASTJSON/source_location.json @@ -1,162 +1,162 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 11 - ] - }, - "id" : 12, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 11, - "linearizedBaseContracts" : - [ - 11 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "body" : - { - "id" : 9, - "nodeType" : "Block", - "src" : "26:19:1", - "statements" : - [ - { - "assignments" : - [ - 3 - ], - "declarations" : - [ - { - "constant" : false, - "id" : 3, - "name" : "x", - "nodeType" : "VariableDeclaration", - "overrides" : null, - "scope" : 9, - "src" : "28:5:1", - "stateVariable" : false, - "storageLocation" : "default", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint8", - "typeString" : "uint8" - }, - "typeName" : null, - "value" : null, - "visibility" : "internal" - } - ], - "id" : 5, - "initialValue" : - { - "argumentTypes" : null, - "hexValue" : "32", - "id" : 4, - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "kind" : "number", - "lValueRequested" : false, - "nodeType" : "Literal", - "src" : "36:1:1", - "subdenomination" : null, - "typeDescriptions" : - { - "typeIdentifier" : "t_rational_2_by_1", - "typeString" : "int_const 2" - }, - "value" : "2" - }, - "nodeType" : "VariableDeclarationStatement", - "src" : "28:9:1" - }, - { - "expression" : - { - "argumentTypes" : null, - "id" : 7, - "isConstant" : false, - "isLValue" : false, - "isPure" : false, - "lValueRequested" : false, - "nodeType" : "UnaryOperation", - "operator" : "++", - "prefix" : false, - "src" : "39:3:1", - "subExpression" : - { - "argumentTypes" : null, - "id" : 6, - "name" : "x", - "nodeType" : "Identifier", - "overloadedDeclarations" : [], - "referencedDeclaration" : 3, - "src" : "39:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint8", - "typeString" : "uint8" - } - }, - "typeDescriptions" : - { - "typeIdentifier" : "t_uint8", - "typeString" : "uint8" - } - }, - "id" : 8, - "nodeType" : "ExpressionStatement", - "src" : "39:3:1" - } - ] - }, - "documentation" : null, - "id" : 10, - "implemented" : true, - "kind" : "function", - "modifiers" : [], - "name" : "f", - "nodeType" : "FunctionDefinition", - "overrides" : null, - "parameters" : - { - "id" : 1, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "23:2:1" - }, - "returnParameters" : - { - "id" : 2, - "nodeType" : "ParameterList", - "parameters" : [], - "src" : "26:0:1" - }, - "scope" : 11, - "src" : "13:32:1", - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - } - ], - "scope" : 12, - "src" : "0:47:1" - } - ], - "src" : "0:48:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 11 + ] + }, + "id": 12, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 11, + "linearizedBaseContracts": + [ + 11 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 9, + "nodeType": "Block", + "src": "26:19:1", + "statements": + [ + { + "assignments": + [ + 3 + ], + "declarations": + [ + { + "constant": false, + "id": 3, + "name": "x", + "nodeType": "VariableDeclaration", + "overrides": null, + "scope": 9, + "src": "28:5:1", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + }, + "typeName": null, + "value": null, + "visibility": "internal" + } + ], + "id": 5, + "initialValue": + { + "argumentTypes": null, + "hexValue": "32", + "id": 4, + "isConstant": false, + "isLValue": false, + "isPure": true, + "kind": "number", + "lValueRequested": false, + "nodeType": "Literal", + "src": "36:1:1", + "subdenomination": null, + "typeDescriptions": + { + "typeIdentifier": "t_rational_2_by_1", + "typeString": "int_const 2" + }, + "value": "2" + }, + "nodeType": "VariableDeclarationStatement", + "src": "28:9:1" + }, + { + "expression": + { + "argumentTypes": null, + "id": 7, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "nodeType": "UnaryOperation", + "operator": "++", + "prefix": false, + "src": "39:3:1", + "subExpression": + { + "argumentTypes": null, + "id": 6, + "name": "x", + "nodeType": "Identifier", + "overloadedDeclarations": [], + "referencedDeclaration": 3, + "src": "39:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "typeDescriptions": + { + "typeIdentifier": "t_uint8", + "typeString": "uint8" + } + }, + "id": 8, + "nodeType": "ExpressionStatement", + "src": "39:3:1" + } + ] + }, + "documentation": null, + "id": 10, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nodeType": "FunctionDefinition", + "overrides": null, + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "23:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "26:0:1" + }, + "scope": 11, + "src": "13:32:1", + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + } + ], + "scope": 12, + "src": "0:47:1" + } + ], + "src": "0:48:1" } diff --git a/test/libsolidity/ASTJSON/source_location_legacy.json b/test/libsolidity/ASTJSON/source_location_legacy.json index 3c56e55f4a78..5c97f2a1e09a 100644 --- a/test/libsolidity/ASTJSON/source_location_legacy.json +++ b/test/libsolidity/ASTJSON/source_location_legacy.json @@ -1,201 +1,201 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 11 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 11 - ], - "name" : "C", - "scope" : 12 - }, - "children" : - [ - { - "attributes" : - { - "documentation" : null, - "implemented" : true, - "isConstructor" : false, - "kind" : "function", - "modifiers" : - [ - null - ], - "name" : "f", - "overrides" : null, - "scope" : 11, - "stateMutability" : "nonpayable", - "superFunction" : null, - "visibility" : "public" - }, - "children" : - [ - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 1, - "name" : "ParameterList", - "src" : "23:2:1" - }, - { - "attributes" : - { - "parameters" : - [ - null - ] - }, - "children" : [], - "id" : 2, - "name" : "ParameterList", - "src" : "26:0:1" - }, - { - "children" : - [ - { - "attributes" : - { - "assignments" : - [ - 3 - ] - }, - "children" : - [ - { - "attributes" : - { - "constant" : false, - "name" : "x", - "overrides" : null, - "scope" : 9, - "stateVariable" : false, - "storageLocation" : "default", - "type" : "uint8", - "typeName" : null, - "value" : null, - "visibility" : "internal" - }, - "children" : [], - "id" : 3, - "name" : "VariableDeclaration", - "src" : "28:5:1" - }, - { - "attributes" : - { - "argumentTypes" : null, - "hexvalue" : "32", - "isConstant" : false, - "isLValue" : false, - "isPure" : true, - "lValueRequested" : false, - "subdenomination" : null, - "token" : "number", - "type" : "int_const 2", - "value" : "2" - }, - "id" : 4, - "name" : "Literal", - "src" : "36:1:1" - } - ], - "id" : 5, - "name" : "VariableDeclarationStatement", - "src" : "28:9:1" - }, - { - "children" : - [ - { - "attributes" : - { - "argumentTypes" : null, - "isConstant" : false, - "isLValue" : false, - "isPure" : false, - "lValueRequested" : false, - "operator" : "++", - "prefix" : false, - "type" : "uint8" - }, - "children" : - [ - { - "attributes" : - { - "argumentTypes" : null, - "overloadedDeclarations" : - [ - null - ], - "referencedDeclaration" : 3, - "type" : "uint8", - "value" : "x" - }, - "id" : 6, - "name" : "Identifier", - "src" : "39:1:1" - } - ], - "id" : 7, - "name" : "UnaryOperation", - "src" : "39:3:1" - } - ], - "id" : 8, - "name" : "ExpressionStatement", - "src" : "39:3:1" - } - ], - "id" : 9, - "name" : "Block", - "src" : "26:19:1" - } - ], - "id" : 10, - "name" : "FunctionDefinition", - "src" : "13:32:1" - } - ], - "id" : 11, - "name" : "ContractDefinition", - "src" : "0:47:1" - } - ], - "id" : 12, - "name" : "SourceUnit", - "src" : "0:48:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 11 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 11 + ], + "name": "C", + "scope": 12 + }, + "children": + [ + { + "attributes": + { + "documentation": null, + "implemented": true, + "isConstructor": false, + "kind": "function", + "modifiers": + [ + null + ], + "name": "f", + "overrides": null, + "scope": 11, + "stateMutability": "nonpayable", + "superFunction": null, + "visibility": "public" + }, + "children": + [ + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 1, + "name": "ParameterList", + "src": "23:2:1" + }, + { + "attributes": + { + "parameters": + [ + null + ] + }, + "children": [], + "id": 2, + "name": "ParameterList", + "src": "26:0:1" + }, + { + "children": + [ + { + "attributes": + { + "assignments": + [ + 3 + ] + }, + "children": + [ + { + "attributes": + { + "constant": false, + "name": "x", + "overrides": null, + "scope": 9, + "stateVariable": false, + "storageLocation": "default", + "type": "uint8", + "typeName": null, + "value": null, + "visibility": "internal" + }, + "children": [], + "id": 3, + "name": "VariableDeclaration", + "src": "28:5:1" + }, + { + "attributes": + { + "argumentTypes": null, + "hexvalue": "32", + "isConstant": false, + "isLValue": false, + "isPure": true, + "lValueRequested": false, + "subdenomination": null, + "token": "number", + "type": "int_const 2", + "value": "2" + }, + "id": 4, + "name": "Literal", + "src": "36:1:1" + } + ], + "id": 5, + "name": "VariableDeclarationStatement", + "src": "28:9:1" + }, + { + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "isConstant": false, + "isLValue": false, + "isPure": false, + "lValueRequested": false, + "operator": "++", + "prefix": false, + "type": "uint8" + }, + "children": + [ + { + "attributes": + { + "argumentTypes": null, + "overloadedDeclarations": + [ + null + ], + "referencedDeclaration": 3, + "type": "uint8", + "value": "x" + }, + "id": 6, + "name": "Identifier", + "src": "39:1:1" + } + ], + "id": 7, + "name": "UnaryOperation", + "src": "39:3:1" + } + ], + "id": 8, + "name": "ExpressionStatement", + "src": "39:3:1" + } + ], + "id": 9, + "name": "Block", + "src": "26:19:1" + } + ], + "id": 10, + "name": "FunctionDefinition", + "src": "13:32:1" + } + ], + "id": 11, + "name": "ContractDefinition", + "src": "0:47:1" + } + ], + "id": 12, + "name": "SourceUnit", + "src": "0:48:1" } diff --git a/test/libsolidity/ASTJSON/using_for_directive.json b/test/libsolidity/ASTJSON/using_for_directive.json index 33caabb477a6..016e8c744132 100644 --- a/test/libsolidity/ASTJSON/using_for_directive.json +++ b/test/libsolidity/ASTJSON/using_for_directive.json @@ -1,87 +1,87 @@ { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 5 - ], - "L" : - [ - 1 - ] - }, - "id" : 6, - "nodeType" : "SourceUnit", - "nodes" : - [ - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "library", - "documentation" : null, - "fullyImplemented" : true, - "id" : 1, - "linearizedBaseContracts" : - [ - 1 - ], - "name" : "L", - "nodeType" : "ContractDefinition", - "nodes" : [], - "scope" : 6, - "src" : "0:12:1" - }, - { - "baseContracts" : [], - "contractDependencies" : [], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "id" : 5, - "linearizedBaseContracts" : - [ - 5 - ], - "name" : "C", - "nodeType" : "ContractDefinition", - "nodes" : - [ - { - "id" : 4, - "libraryName" : - { - "contractScope" : null, - "id" : 2, - "name" : "L", - "nodeType" : "UserDefinedTypeName", - "referencedDeclaration" : 1, - "src" : "32:1:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_contract$_L_$1", - "typeString" : "library L" - } - }, - "nodeType" : "UsingForDirective", - "src" : "26:17:1", - "typeName" : - { - "id" : 3, - "name" : "uint", - "nodeType" : "ElementaryTypeName", - "src" : "38:4:1", - "typeDescriptions" : - { - "typeIdentifier" : "t_uint256", - "typeString" : "uint256" - } - } - } - ], - "scope" : 6, - "src" : "13:32:1" - } - ], - "src" : "0:46:1" + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ], + "L": + [ + 1 + ] + }, + "id": 6, + "nodeType": "SourceUnit", + "nodes": + [ + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "library", + "documentation": null, + "fullyImplemented": true, + "id": 1, + "linearizedBaseContracts": + [ + 1 + ], + "name": "L", + "nodeType": "ContractDefinition", + "nodes": [], + "scope": 6, + "src": "0:12:1" + }, + { + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "id": 5, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "id": 4, + "libraryName": + { + "contractScope": null, + "id": 2, + "name": "L", + "nodeType": "UserDefinedTypeName", + "referencedDeclaration": 1, + "src": "32:1:1", + "typeDescriptions": + { + "typeIdentifier": "t_contract$_L_$1", + "typeString": "library L" + } + }, + "nodeType": "UsingForDirective", + "src": "26:17:1", + "typeName": + { + "id": 3, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "38:4:1", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + } + } + ], + "scope": 6, + "src": "13:32:1" + } + ], + "src": "0:46:1" } diff --git a/test/libsolidity/ASTJSON/using_for_directive_legacy.json b/test/libsolidity/ASTJSON/using_for_directive_legacy.json index 0827ef90f55d..889fb56c0ea6 100644 --- a/test/libsolidity/ASTJSON/using_for_directive_legacy.json +++ b/test/libsolidity/ASTJSON/using_for_directive_legacy.json @@ -1,110 +1,110 @@ { - "attributes" : - { - "absolutePath" : "a", - "exportedSymbols" : - { - "C" : - [ - 5 - ], - "L" : - [ - 1 - ] - } - }, - "children" : - [ - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "library", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 1 - ], - "name" : "L", - "nodes" : - [ - null - ], - "scope" : 6 - }, - "id" : 1, - "name" : "ContractDefinition", - "src" : "0:12:1" - }, - { - "attributes" : - { - "baseContracts" : - [ - null - ], - "contractDependencies" : - [ - null - ], - "contractKind" : "contract", - "documentation" : null, - "fullyImplemented" : true, - "linearizedBaseContracts" : - [ - 5 - ], - "name" : "C", - "scope" : 6 - }, - "children" : - [ - { - "children" : - [ - { - "attributes" : - { - "contractScope" : null, - "name" : "L", - "referencedDeclaration" : 1, - "type" : "library L" - }, - "id" : 2, - "name" : "UserDefinedTypeName", - "src" : "32:1:1" - }, - { - "attributes" : - { - "name" : "uint", - "type" : "uint256" - }, - "id" : 3, - "name" : "ElementaryTypeName", - "src" : "38:4:1" - } - ], - "id" : 4, - "name" : "UsingForDirective", - "src" : "26:17:1" - } - ], - "id" : 5, - "name" : "ContractDefinition", - "src" : "13:32:1" - } - ], - "id" : 6, - "name" : "SourceUnit", - "src" : "0:46:1" + "attributes": + { + "absolutePath": "a", + "exportedSymbols": + { + "C": + [ + 5 + ], + "L": + [ + 1 + ] + } + }, + "children": + [ + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "library", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 1 + ], + "name": "L", + "nodes": + [ + null + ], + "scope": 6 + }, + "id": 1, + "name": "ContractDefinition", + "src": "0:12:1" + }, + { + "attributes": + { + "baseContracts": + [ + null + ], + "contractDependencies": + [ + null + ], + "contractKind": "contract", + "documentation": null, + "fullyImplemented": true, + "linearizedBaseContracts": + [ + 5 + ], + "name": "C", + "scope": 6 + }, + "children": + [ + { + "children": + [ + { + "attributes": + { + "contractScope": null, + "name": "L", + "referencedDeclaration": 1, + "type": "library L" + }, + "id": 2, + "name": "UserDefinedTypeName", + "src": "32:1:1" + }, + { + "attributes": + { + "name": "uint", + "type": "uint256" + }, + "id": 3, + "name": "ElementaryTypeName", + "src": "38:4:1" + } + ], + "id": 4, + "name": "UsingForDirective", + "src": "26:17:1" + } + ], + "id": 5, + "name": "ContractDefinition", + "src": "13:32:1" + } + ], + "id": 6, + "name": "SourceUnit", + "src": "0:46:1" } From c6152b80595c4a1cc41afb2fab13db8180eb7833 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Wed, 23 Oct 2019 13:08:17 +0200 Subject: [PATCH 046/283] Compile fix. --- libsolidity/codegen/ExpressionCompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 5720cb4b9268..3d43833010f7 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1281,7 +1281,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) if (FunctionCall const* funCall = dynamic_cast(&_memberAccess.expression())) if (auto const* addr = dynamic_cast(&funCall->expression())) if ( - addr->typeName().token() == Token::Address && + addr->type().typeName().token() == Token::Address && funCall->arguments().size() == 1 ) if (auto arg = dynamic_cast( funCall->arguments().front().get())) From 76c72ba89fdc4f57be5f9bfea4e04d83f0328f56 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Wed, 23 Oct 2019 16:32:41 +0200 Subject: [PATCH 047/283] Fixes signedness (causes compilation failure on MSVC). --- libsolidity/codegen/ContractCompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 587b13446612..09a1c33dab60 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -769,7 +769,7 @@ bool ContractCompiler::visit(TryStatement const& _tryStatement) CompilerContext::LocationSetter locationSetter(m_context, _tryStatement); compileExpression(_tryStatement.externalCall()); - unsigned returnSize = _tryStatement.externalCall().annotation().type->sizeOnStack(); + int const returnSize = static_cast(_tryStatement.externalCall().annotation().type->sizeOnStack()); // Stack: [ return values] eth::AssemblyItem successTag = m_context.appendConditionalJump(); From e40c498260a4be0840ed251a78f0992e8ab81b12 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Tue, 10 Sep 2019 13:35:55 +0200 Subject: [PATCH 048/283] Adapting the tests to strict inline assembly. --- test/cmdlineTests/strict_asm_jump/err | 2 +- test/libsolidity/InlineAssembly.cpp | 163 +++--------------- test/libsolidity/SolidityEndToEndTest.cpp | 8 +- test/libsolidity/ViewPureChecker.cpp | 2 +- .../inlineAssembly/function_call_to_label.sol | 13 -- .../inlineAssembly/function_without_call.sol | 2 +- .../invalid/bare_instructions_disallowed.sol | 3 +- .../invalid/jump_disallowed.sol | 2 +- .../invalid/jump_invalid_label.sol | 10 -- .../invalid/label_disallowed.sol | 3 +- .../invalid/leave_items_on_tack.sol | 3 +- .../invalid/literals_on_stack_disallowed.sol | 3 +- .../invalid/no_identifier_assignment.sol | 9 - .../invalid/no_identifier_label.sol | 9 - .../invalid/unbalanced_negative_stack.sol | 3 +- .../invalid/unbalanced_positive_stack.sol | 3 +- .../storage_reference_empty_offset.sol | 4 +- .../storage_reference_empty_slot.sol | 4 +- .../syntaxTests/viewPureChecker/assembly.sol | 4 +- test/libyul/Parser.cpp | 7 - 20 files changed, 45 insertions(+), 212 deletions(-) delete mode 100644 test/libsolidity/syntaxTests/inlineAssembly/function_call_to_label.sol delete mode 100644 test/libsolidity/syntaxTests/inlineAssembly/invalid/jump_invalid_label.sol delete mode 100644 test/libsolidity/syntaxTests/inlineAssembly/invalid/no_identifier_assignment.sol delete mode 100644 test/libsolidity/syntaxTests/inlineAssembly/invalid/no_identifier_label.sol diff --git a/test/cmdlineTests/strict_asm_jump/err b/test/cmdlineTests/strict_asm_jump/err index 8463daa8211c..b4f25866a0b7 100644 --- a/test/cmdlineTests/strict_asm_jump/err +++ b/test/cmdlineTests/strict_asm_jump/err @@ -1,5 +1,5 @@ Warning: Yul and its optimizer are still experimental. Please use the output with care. -Error: Function not found. +Error: Jump instructions and labels are low-level EVM features that can lead to incorrect stack access. Because of that they are disallowed in strict assembly. Use functions, "switch", "if" or "for" statements instead. --> strict_asm_jump/input.sol:1:3: | 1 | { jump(1) } diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 76985f54d10b..18c21c41c175 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -188,22 +188,22 @@ BOOST_AUTO_TEST_CASE(surplus_input) BOOST_AUTO_TEST_CASE(simple_instructions) { - BOOST_CHECK(successParse("{ dup1 dup1 mul dup1 sub pop }")); + BOOST_CHECK(successParse("{ let y := mul(0x10, mul(0x20, mload(0x40)))}")); } BOOST_AUTO_TEST_CASE(selfdestruct) { - BOOST_CHECK(successParse("{ 0x02 selfdestruct }")); + BOOST_CHECK(successParse("{ selfdestruct(0x02) }")); } BOOST_AUTO_TEST_CASE(keywords) { - BOOST_CHECK(successParse("{ 1 2 byte 2 return address pop }")); + BOOST_CHECK(successParse("{ return (byte(1, 2), 2) pop(address()) }")); } BOOST_AUTO_TEST_CASE(constants) { - BOOST_CHECK(successParse("{ 7 8 mul pop }")); + BOOST_CHECK(successParse("{ pop(mul(7, 8)) }")); } BOOST_AUTO_TEST_CASE(vardecl) @@ -237,29 +237,14 @@ BOOST_AUTO_TEST_CASE(vardecl_empty) BOOST_CHECK(successParse("{ let x }")); } -BOOST_AUTO_TEST_CASE(assignment) -{ - BOOST_CHECK(successParse("{ let x := 2 7 8 add =: x }")); -} - -BOOST_AUTO_TEST_CASE(label) -{ - BOOST_CHECK(successParse("{ 7 abc: 8 eq abc jump pop }")); -} - -BOOST_AUTO_TEST_CASE(label_complex) -{ - BOOST_CHECK(successParse("{ 7 abc: 8 eq jump(abc) jumpi(eq(7, 8), abc) pop }")); -} - BOOST_AUTO_TEST_CASE(functional) { - BOOST_CHECK(successParse("{ let x := 2 add(7, mul(6, x)) mul(7, 8) add =: x }")); + BOOST_CHECK(successParse("{ let x := 2 x := add(add(7, mul(6, x)), mul(7, 8)) }")); } BOOST_AUTO_TEST_CASE(functional_partial) { - CHECK_PARSE_ERROR("{ let x := byte }", ParserError, "Expected '(' (instruction \"byte\" expects 2 arguments)"); + CHECK_PARSE_ERROR("{ let x := byte }", ParserError, "Expected '(' but got '}'"); } BOOST_AUTO_TEST_CASE(functional_partial_success) @@ -274,12 +259,12 @@ BOOST_AUTO_TEST_CASE(functional_assignment) BOOST_AUTO_TEST_CASE(functional_assignment_complex) { - BOOST_CHECK(successParse("{ let x := 2 x := add(7, mul(6, x)) mul(7, 8) add }")); + BOOST_CHECK(successParse("{ let x := 2 x := add(add(7, mul(6, x)), mul(7, 8)) }")); } BOOST_AUTO_TEST_CASE(vardecl_complex) { - BOOST_CHECK(successParse("{ let y := 2 let x := add(7, mul(6, y)) add mul(7, 8) }")); + BOOST_CHECK(successParse("{ let y := 2 let x := add(add(7, mul(6, y)), mul(7, 8)) }")); } BOOST_AUTO_TEST_CASE(variable_use_before_decl) @@ -303,7 +288,7 @@ BOOST_AUTO_TEST_CASE(if_statement_scope) BOOST_AUTO_TEST_CASE(if_statement_invalid) { - CHECK_PARSE_ERROR("{ if mload {} }", ParserError, "Expected '(' (instruction \"mload\" expects 1 arguments)"); + CHECK_PARSE_ERROR("{ if mload {} }", ParserError, "Expected '(' but got '{'"); BOOST_CHECK("{ if calldatasize() {}"); CHECK_PARSE_ERROR("{ if mstore(1, 1) {} }", TypeError, "Expected expression to return one item to the stack, but did return 0 items"); CHECK_PARSE_ERROR("{ if 32 let x := 3 }", ParserError, "Expected '{' but got reserved keyword 'let'"); @@ -333,7 +318,7 @@ BOOST_AUTO_TEST_CASE(switch_duplicate_case) BOOST_AUTO_TEST_CASE(switch_invalid_expression) { CHECK_PARSE_ERROR("{ switch {} default {} }", ParserError, "Literal, identifier or instruction expected."); - CHECK_PARSE_ERROR("{ switch mload default {} }", ParserError, "Expected '(' (instruction \"mload\" expects 1 arguments)"); + CHECK_PARSE_ERROR("{ switch mload default {} }", ParserError, "Expected '(' but got reserved keyword 'default'"); CHECK_PARSE_ERROR("{ switch mstore(1, 1) default {} }", TypeError, "Expected expression to return one item to the stack, but did return 0 items"); } @@ -369,7 +354,7 @@ BOOST_AUTO_TEST_CASE(for_invalid_expression) CHECK_PARSE_ERROR("{ for 1 1 {} {} }", ParserError, "Expected '{' but got 'Number'"); CHECK_PARSE_ERROR("{ for {} 1 1 {} }", ParserError, "Expected '{' but got 'Number'"); CHECK_PARSE_ERROR("{ for {} 1 {} 1 }", ParserError, "Expected '{' but got 'Number'"); - CHECK_PARSE_ERROR("{ for {} mload {} {} }", ParserError, "Expected '(' (instruction \"mload\" expects 1 arguments)"); + CHECK_PARSE_ERROR("{ for {} mload {} {} }", ParserError, "Expected '(' but got '{'"); CHECK_PARSE_ERROR("{ for {} mstore(1, 1) {} {} }", TypeError, "Expected expression to return one item to the stack, but did return 0 items"); } @@ -463,7 +448,7 @@ BOOST_AUTO_TEST_CASE(functions_in_parallel_scopes) BOOST_AUTO_TEST_CASE(variable_access_cross_functions) { - CHECK_PARSE_ERROR("{ let x := 2 function g() { x pop } }", DeclarationError, "Identifier not found."); + CHECK_PARSE_ERROR("{ let x := 2 function g() { pop(x) } }", DeclarationError, "Identifier not found."); } BOOST_AUTO_TEST_CASE(invalid_tuple_assignment) @@ -516,46 +501,6 @@ BOOST_AUTO_TEST_CASE(multiple_assignment) BOOST_AUTO_TEST_SUITE_END() -BOOST_AUTO_TEST_SUITE(LooseStrictMode) - -BOOST_AUTO_TEST_CASE(no_opcodes_in_strict) -{ - BOOST_CHECK(successParse("{ pop(callvalue) }")); - BOOST_CHECK(successParse("{ callvalue pop }")); - CHECK_STRICT_ERROR("{ pop(callvalue) }", ParserError, "Expected '(' but got ')'"); - CHECK_STRICT_ERROR("{ callvalue pop }", ParserError, "Call or assignment expected"); - SUCCESS_STRICT("{ pop(callvalue()) }"); - BOOST_CHECK(successParse("{ switch callvalue case 0 {} }")); - CHECK_STRICT_ERROR("{ switch callvalue case 0 {} }", ParserError, "Expected '(' but got reserved keyword 'case'"); -} - -BOOST_AUTO_TEST_CASE(no_labels_in_strict) -{ - BOOST_CHECK(successParse("{ a: }")); - CHECK_STRICT_ERROR("{ a: }", ParserError, "Labels are not supported"); -} - -BOOST_AUTO_TEST_CASE(no_stack_assign_in_strict) -{ - BOOST_CHECK(successParse("{ let x 4 =: x }")); - CHECK_STRICT_ERROR("{ let x 4 =: x }", ParserError, "Call or assignment expected."); -} - -BOOST_AUTO_TEST_CASE(no_dup_swap_in_strict) -{ - BOOST_CHECK(successParse("{ swap1 }")); - CHECK_STRICT_ERROR("{ swap1 }", ParserError, "Call or assignment expected."); - BOOST_CHECK(successParse("{ dup1 pop }")); - CHECK_STRICT_ERROR("{ dup1 pop }", ParserError, "Call or assignment expected."); - BOOST_CHECK(successParse("{ swap2 }")); - CHECK_STRICT_ERROR("{ swap2 }", ParserError, "Call or assignment expected."); - BOOST_CHECK(successParse("{ dup2 pop }")); - CHECK_STRICT_ERROR("{ dup2 pop }", ParserError, "Call or assignment expected."); - CHECK_PARSE_ERROR("{ switch dup1 case 0 {} }", ParserError, "Instruction \"dup1\" not allowed in this context"); -} - -BOOST_AUTO_TEST_SUITE_END() - BOOST_AUTO_TEST_SUITE(Printing) BOOST_AUTO_TEST_CASE(print_smoke) @@ -565,12 +510,12 @@ BOOST_AUTO_TEST_CASE(print_smoke) BOOST_AUTO_TEST_CASE(print_instructions) { - parsePrintCompare("{\n 7\n 8\n mul\n dup10\n add\n pop\n}"); + parsePrintCompare("{ pop(7) }"); } BOOST_AUTO_TEST_CASE(print_subblock) { - parsePrintCompare("{\n {\n dup4\n add\n }\n}"); + parsePrintCompare("{ { pop(7) } }"); } BOOST_AUTO_TEST_CASE(print_functional) @@ -578,14 +523,9 @@ BOOST_AUTO_TEST_CASE(print_functional) parsePrintCompare("{ let x := mul(sload(0x12), 7) }"); } -BOOST_AUTO_TEST_CASE(print_label) -{ - parsePrintCompare("{\n loop:\n jump(loop)\n}", true); -} - BOOST_AUTO_TEST_CASE(print_assignments) { - parsePrintCompare("{\n let x := mul(2, 3)\n 7\n =: x\n x := add(1, 2)\n}"); + parsePrintCompare("{\n let x := mul(2, 3)\n pop(7)\n x := add(1, 2)\n}"); } BOOST_AUTO_TEST_CASE(print_multi_assignments) @@ -595,7 +535,7 @@ BOOST_AUTO_TEST_CASE(print_multi_assignments) BOOST_AUTO_TEST_CASE(print_string_literals) { - parsePrintCompare("{\n \"\\n'\\xab\\x95\\\"\"\n pop\n}"); + parsePrintCompare("{ let x := \"\\n'\\xab\\x95\\\"\" }"); } BOOST_AUTO_TEST_CASE(print_string_literal_unicode) @@ -661,39 +601,21 @@ BOOST_AUTO_TEST_CASE(oversize_string_literals) CHECK_ASSEMBLE_ERROR("{ let x := \"123456789012345678901234567890123\" }", TypeError, "String literal too long"); } -BOOST_AUTO_TEST_CASE(assignment_after_tag) -{ - BOOST_CHECK(successParse("{ let x := 1 { 7 tag: =: x } }")); -} - BOOST_AUTO_TEST_CASE(magic_variables) { - CHECK_ASSEMBLE_ERROR("{ this pop }", DeclarationError, "Identifier not found"); - CHECK_ASSEMBLE_ERROR("{ ecrecover pop }", DeclarationError, "Identifier not found"); - BOOST_CHECK(successAssemble("{ let ecrecover := 1 ecrecover pop }")); + CHECK_ASSEMBLE_ERROR("{ pop(this) }", DeclarationError, "Identifier not found"); + CHECK_ASSEMBLE_ERROR("{ pop(ecrecover) }", DeclarationError, "Identifier not found"); + BOOST_CHECK(successAssemble("{ let ecrecover := 1 pop(ecrecover) }")); } BOOST_AUTO_TEST_CASE(stack_variables) { - BOOST_CHECK(successAssemble("{ let y := 3 { 2 { let x := y } pop} }")); -} - -BOOST_AUTO_TEST_CASE(imbalanced_stack) -{ - BOOST_CHECK(successAssemble("{ 1 2 mul pop }", false)); - CHECK_ASSEMBLE_ERROR("{ 1 }", DeclarationError, "Unbalanced stack at the end of a block: 1 surplus item(s)."); - CHECK_ASSEMBLE_ERROR("{ pop }", DeclarationError, "Unbalanced stack at the end of a block: 1 missing item(s)."); - BOOST_CHECK(successAssemble("{ let x := 4 7 add }", false)); -} - -BOOST_AUTO_TEST_CASE(error_tag) -{ - CHECK_ERROR("{ jump(invalidJumpLabel) }", true, DeclarationError, "Identifier not found", true); + BOOST_CHECK(successAssemble("{ let y := 3 { let z := 2 { let x := y } } }")); } BOOST_AUTO_TEST_CASE(designated_invalid_instruction) { - BOOST_CHECK(successAssemble("{ invalid }")); + BOOST_CHECK(successAssemble("{ invalid() }")); } BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_declaration) @@ -701,16 +623,6 @@ BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_declaration) CHECK_ASSEMBLE_ERROR("{ let gas := 1 }", ParserError, "Cannot use builtin"); } -BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_assignment) -{ - CHECK_ASSEMBLE_ERROR("{ 2 =: gas }", ParserError, "Identifier expected, got builtin symbol"); -} - -BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_functional_assignment) -{ - CHECK_ASSEMBLE_ERROR("{ gas := 2 }", ParserError, "Variable name must precede \":=\""); -} - BOOST_AUTO_TEST_CASE(revert) { BOOST_CHECK(successAssemble("{ revert(0, 0) }")); @@ -772,18 +684,10 @@ BOOST_AUTO_TEST_CASE(large_constant) BOOST_AUTO_TEST_CASE(keccak256) { - BOOST_CHECK(successAssemble("{ 0 0 keccak256 pop }")); BOOST_CHECK(successAssemble("{ pop(keccak256(0, 0)) }")); } BOOST_AUTO_TEST_CASE(returndatasize) -{ - if (!dev::test::Options::get().evmVersion().supportsReturndata()) - return; - BOOST_CHECK(successAssemble("{ let r := returndatasize }")); -} - -BOOST_AUTO_TEST_CASE(returndatasize_functional) { if (!dev::test::Options::get().evmVersion().supportsReturndata()) return; @@ -794,7 +698,7 @@ BOOST_AUTO_TEST_CASE(returndatacopy) { if (!dev::test::Options::get().evmVersion().supportsReturndata()) return; - BOOST_CHECK(successAssemble("{ 64 32 0 returndatacopy }")); + BOOST_CHECK(successAssemble("{ returndatacopy(0, 32, 64) }")); } BOOST_AUTO_TEST_CASE(returndatacopy_functional) @@ -836,27 +740,10 @@ BOOST_AUTO_TEST_CASE(shift_constantinople_warning) CHECK_PARSE_WARNING("{ pop(sar(10, 32)) }", TypeError, "The \"sar\" instruction is only available for Constantinople-compatible VMs"); } -BOOST_AUTO_TEST_CASE(chainid_instanbul_warning) -{ - if (dev::test::Options::get().evmVersion().hasChainID()) - return; - CHECK_PARSE_WARNING("{ pop(chainid()) }", TypeError, "The \"chainid\" instruction is only available for Istanbul-compatible VMs"); -} - -BOOST_AUTO_TEST_CASE(selfbalance_instanbul_warning) -{ - if (dev::test::Options::get().evmVersion().hasSelfBalance()) - return; - CHECK_PARSE_WARNING("{ pop(selfbalance()) }", TypeError, "The \"selfbalance\" instruction is only available for Istanbul-compatible VMs"); -} - -BOOST_AUTO_TEST_CASE(jump_warning) +BOOST_AUTO_TEST_CASE(jump_error) { - CHECK_PARSE_WARNING("{ 1 jump }", Warning, "Jump instructions"); - CHECK_PARSE_WARNING("{ 1 2 jumpi }", Warning, "Jump instructions"); - CHECK_PARSE_WARNING("{ jump(44) }", Warning, "Jump instructions"); - CHECK_PARSE_WARNING("{ jumpi(44, 2) }", Warning, "Jump instructions"); - CHECK_PARSE_WARNING("{ a: }", Warning, "Jump instructions"); + CHECK_PARSE_WARNING("{ jump(44) }", SyntaxError, "Jump instructions and labels are low-level EVM features"); + CHECK_PARSE_WARNING("{ jumpi(44, 2) }", SyntaxError, "Jump instructions and labels are low-level EVM features"); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index f9e5f6fc3bc2..dd9ba2d3926c 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -10274,7 +10274,7 @@ BOOST_AUTO_TEST_CASE(correctly_initialize_memory_array_in_constructor) // Make memory dirty. assembly { for { let i := 0 } lt(i, 64) { i := add(i, 1) } { - mstore(msize, not(0)) + mstore(msize(), not(0)) } } uint16[3] memory c; @@ -12920,7 +12920,7 @@ BOOST_AUTO_TEST_CASE(snark) input[3] = p2.Y; bool success; assembly { - success := call(sub(gas, 2000), 6, 0, input, 0xc0, r, 0x60) + success := call(sub(gas(), 2000), 6, 0, input, 0xc0, r, 0x60) // Use "invalid" to make gas estimation work switch success case 0 { invalid() } } @@ -12936,7 +12936,7 @@ BOOST_AUTO_TEST_CASE(snark) input[2] = s; bool success; assembly { - success := call(sub(gas, 2000), 7, 0, input, 0x80, r, 0x60) + success := call(sub(gas(), 2000), 7, 0, input, 0x80, r, 0x60) // Use "invalid" to make gas estimation work switch success case 0 { invalid() } } @@ -12964,7 +12964,7 @@ BOOST_AUTO_TEST_CASE(snark) uint[1] memory out; bool success; assembly { - success := call(sub(gas, 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20) + success := call(sub(gas(), 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20) // Use "invalid" to make gas estimation work switch success case 0 { invalid() } } diff --git a/test/libsolidity/ViewPureChecker.cpp b/test/libsolidity/ViewPureChecker.cpp index 176a349d3e10..f1176b865769 100644 --- a/test/libsolidity/ViewPureChecker.cpp +++ b/test/libsolidity/ViewPureChecker.cpp @@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(assembly_staticcall) string text = R"( contract C { function i() view public { - assembly { pop(staticcall(gas, 1, 2, 3, 4, 5)) } + assembly { pop(staticcall(gas(), 1, 2, 3, 4, 5)) } } } )"; diff --git a/test/libsolidity/syntaxTests/inlineAssembly/function_call_to_label.sol b/test/libsolidity/syntaxTests/inlineAssembly/function_call_to_label.sol deleted file mode 100644 index 150fb9385867..000000000000 --- a/test/libsolidity/syntaxTests/inlineAssembly/function_call_to_label.sol +++ /dev/null @@ -1,13 +0,0 @@ -contract C { - function f() public pure { - assembly { - l: - - l() - } - } -} -// ---- -// SyntaxError: (63-64): The use of labels is disallowed. Please use "if", "switch", "for" or function calls instead. -// SyntaxError: (63-64): Jump instructions and labels are low-level EVM features that can lead to incorrect stack access. Because of that they are discouraged. Please consider using "switch", "if" or "for" statements instead. -// TypeError: (73-74): Attempt to call label instead of function. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/function_without_call.sol b/test/libsolidity/syntaxTests/inlineAssembly/function_without_call.sol index 8557e2fa4575..073f3fbcbfe5 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/function_without_call.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/function_without_call.sol @@ -8,4 +8,4 @@ contract C { } } // ---- -// TypeError: (86-87): Function k used without being called. +// ParserError: (92-93): Call or assignment expected. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/bare_instructions_disallowed.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/bare_instructions_disallowed.sol index 7315d5d1d5d9..4dd8b76dfb36 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/bare_instructions_disallowed.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/bare_instructions_disallowed.sol @@ -7,5 +7,4 @@ contract C { } } // ---- -// SyntaxError: (75-82): The use of non-functional instructions is disallowed. Please use functional notation instead. -// SyntaxError: (95-98): The use of non-functional instructions is disallowed. Please use functional notation instead. +// ParserError: (95-98): Expected '(' but got identifier diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/jump_disallowed.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/jump_disallowed.sol index 6cb35d6dfc7f..302dcaec97be 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/jump_disallowed.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/jump_disallowed.sol @@ -6,4 +6,4 @@ contract C { } } // ---- -// SyntaxError: (75-82): Jump instructions and labels are low-level EVM features that can lead to incorrect stack access. Because of that they are discouraged. Please consider using "switch", "if" or "for" statements instead. +// SyntaxError: (75-79): Jump instructions and labels are low-level EVM features that can lead to incorrect stack access. Because of that they are disallowed in strict assembly. Use functions, "switch", "if" or "for" statements instead. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/jump_invalid_label.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/jump_invalid_label.sol deleted file mode 100644 index 1ad8038696bf..000000000000 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/jump_invalid_label.sol +++ /dev/null @@ -1,10 +0,0 @@ -contract C { - function f() public pure { - assembly { - jump(xy) - } - } -} -// ---- -// DeclarationError: (68-70): Identifier not found. -// SyntaxError: (63-71): Jump instructions and labels are low-level EVM features that can lead to incorrect stack access. Because of that they are discouraged. Please consider using "switch", "if" or "for" statements instead. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/label_disallowed.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/label_disallowed.sol index 0d7bacb4f9f8..d3f34d0ec4f0 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/label_disallowed.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/label_disallowed.sol @@ -6,5 +6,4 @@ contract C { } } // ---- -// SyntaxError: (75-80): The use of labels is disallowed. Please use "if", "switch", "for" or function calls instead. -// SyntaxError: (75-80): Jump instructions and labels are low-level EVM features that can lead to incorrect stack access. Because of that they are discouraged. Please consider using "switch", "if" or "for" statements instead. +// ParserError: (80-81): Call or assignment expected. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/leave_items_on_tack.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/leave_items_on_tack.sol index 8538a2a0de24..5b410d4b6379 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/leave_items_on_tack.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/leave_items_on_tack.sol @@ -6,5 +6,4 @@ contract C { } } // ---- -// SyntaxError: (75-83): Top-level expressions are not supposed to return values (this expression returns 1 value). Use ``pop()`` or assign them. -// DeclarationError: (61-93): Unbalanced stack at the end of a block: 1 surplus item(s). +// TypeError: (75-83): Top-level expressions are not supposed to return values (this expression returns 1 value). Use ``pop()`` or assign them. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/literals_on_stack_disallowed.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/literals_on_stack_disallowed.sol index 62fe71710024..b2649cd8cd93 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/literals_on_stack_disallowed.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/literals_on_stack_disallowed.sol @@ -6,5 +6,4 @@ contract C { } } // ---- -// SyntaxError: (75-76): Top-level expressions are not supposed to return values (this expression returns 1 value). Use ``pop()`` or assign them. -// DeclarationError: (61-86): Unbalanced stack at the end of a block: 1 surplus item(s). +// ParserError: (85-86): Call or assignment expected. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/no_identifier_assignment.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/no_identifier_assignment.sol deleted file mode 100644 index 1ec898ea5ae8..000000000000 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/no_identifier_assignment.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract C { - function f() public pure { - assembly { - return := 1 - } - } -} -// ---- -// ParserError: (70-72): Variable name must precede ":=" in assignment. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/no_identifier_label.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/no_identifier_label.sol deleted file mode 100644 index 4a1e72c63a54..000000000000 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/no_identifier_label.sol +++ /dev/null @@ -1,9 +0,0 @@ -contract C { - function f() public pure { - assembly { - return : 1 - } - } -} -// ---- -// ParserError: (70-71): Label name must precede ":". diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_negative_stack.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_negative_stack.sol index 342afc464b76..73f4ed76ae3f 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_negative_stack.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_negative_stack.sol @@ -6,5 +6,4 @@ contract test { } } // ---- -// SyntaxError: (73-76): The use of non-functional instructions is disallowed. Please use functional notation instead. -// DeclarationError: (59-86): Unbalanced stack at the end of a block: 1 missing item(s). +// ParserError: (85-86): Expected '(' but got '}' diff --git a/test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_positive_stack.sol b/test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_positive_stack.sol index e9599f4bdb16..25aad5bcd96e 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_positive_stack.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/invalid/unbalanced_positive_stack.sol @@ -6,5 +6,4 @@ contract test { } } // ---- -// SyntaxError: (73-74): Top-level expressions are not supposed to return values (this expression returns 1 value). Use ``pop()`` or assign them. -// DeclarationError: (59-84): Unbalanced stack at the end of a block: 1 surplus item(s). +// ParserError: (83-84): Call or assignment expected. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_empty_offset.sol b/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_empty_offset.sol index ec23a2630cf0..8666889b8d0f 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_empty_offset.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_empty_offset.sol @@ -1,9 +1,9 @@ contract C { function f() public pure { assembly { - _offset + let x := _offset } } } // ---- -// DeclarationError: (75-82): In variable names _slot and _offset can only be used as a suffix. +// DeclarationError: (84-91): In variable names _slot and _offset can only be used as a suffix. diff --git a/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_empty_slot.sol b/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_empty_slot.sol index d493a68a54c6..05935f19fbb1 100644 --- a/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_empty_slot.sol +++ b/test/libsolidity/syntaxTests/inlineAssembly/storage_reference_empty_slot.sol @@ -1,9 +1,9 @@ contract C { function f() public pure { assembly { - _slot + let x := _slot } } } // ---- -// DeclarationError: (75-80): In variable names _slot and _offset can only be used as a suffix. +// DeclarationError: (84-89): In variable names _slot and _offset can only be used as a suffix. diff --git a/test/libsolidity/syntaxTests/viewPureChecker/assembly.sol b/test/libsolidity/syntaxTests/viewPureChecker/assembly.sol index 0a11dc3ae526..92b5e4c8b502 100644 --- a/test/libsolidity/syntaxTests/viewPureChecker/assembly.sol +++ b/test/libsolidity/syntaxTests/viewPureChecker/assembly.sol @@ -9,7 +9,7 @@ contract C { assembly { x := 7 } } function g() view public { - assembly { for {} 1 { pop(sload(0)) } { } pop(gas) } + assembly { for {} 1 { pop(sload(0)) } { } pop(gas()) } } function h() view public { assembly { function g() { pop(blockhash(20)) } } @@ -18,6 +18,6 @@ contract C { assembly { pop(call(0, 1, 2, 3, 4, 5, 6)) } } function k() public { - assembly { pop(call(gas, 1, 2, 3, 4, 5, 6)) } + assembly { pop(call(gas(), 1, 2, 3, 4, 5, 6)) } } } diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 899f40f720e4..575329abe046 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -208,11 +208,6 @@ BOOST_AUTO_TEST_CASE(tuple_assignment) BOOST_CHECK(successParse("{ function f() -> a:u256, b:u256, c:u256 {} let x:u256, y:u256, z:u256 := f() }")); } -BOOST_AUTO_TEST_CASE(label) -{ - CHECK_ERROR("{ label: }", ParserError, "Labels are not supported."); -} - BOOST_AUTO_TEST_CASE(instructions) { CHECK_ERROR("{ pop }", ParserError, "Call or assignment expected."); @@ -549,11 +544,9 @@ BOOST_AUTO_TEST_CASE(builtins_parser) SimpleDialect dialect; CHECK_ERROR_DIALECT("{ let builtin := 6 }", ParserError, "Cannot use builtin function name \"builtin\" as identifier name.", dialect); CHECK_ERROR_DIALECT("{ function builtin() {} }", ParserError, "Cannot use builtin function name \"builtin\" as identifier name.", dialect); - CHECK_ERROR_DIALECT("{ builtin := 6 }", ParserError, "Variable name must precede \":=\" in assignment.", dialect); CHECK_ERROR_DIALECT("{ function f(x) { f(builtin) } }", ParserError, "Expected '(' but got ')'", dialect); CHECK_ERROR_DIALECT("{ function f(builtin) {}", ParserError, "Cannot use builtin function name \"builtin\" as identifier name.", dialect); CHECK_ERROR_DIALECT("{ function f() -> builtin {}", ParserError, "Cannot use builtin function name \"builtin\" as identifier name.", dialect); - CHECK_ERROR_DIALECT("{ function g() -> a,b {} builtin, builtin2 := g() }", ParserError, "Variable name must precede \",\" in multiple assignment.", dialect); } BOOST_AUTO_TEST_CASE(builtins_analysis) From 99034abcbfc358508ce4a8c687ce9d972c3d98b9 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Tue, 10 Sep 2019 15:31:18 +0200 Subject: [PATCH 049/283] ChangeLog: Adds entry changing inline assembly to strict mode. --- Changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 7232f3f8672c..f234fd5b9ebb 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,9 +10,9 @@ Breaking changes: * General: New reserved keywords: ``virtual``. * Standard JSON Interface: Add option to disable or choose hash method between IPFS and Swarm for the bytecode metadata. * Syntax: ``push(element)`` for dynamic storage arrays do not return the new length anymore. + * Inline Assembly: Only strict inline assembly is allowed. * Type checker: Resulting type of exponentiation is equal to the type of the base. Also allow signed types for the base. - Language Features: * Allow global enums and structs. * Allow underscores as delimiters in hex strings. From 5a52fa547ed0e3df5699d9ac8da6ad384a6d2fd2 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Tue, 10 Sep 2019 15:32:18 +0200 Subject: [PATCH 050/283] Assembly: Changed parser to use strict assembly mode. --- libsolidity/parsing/Parser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 59c76d69a708..27374ca0f500 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1152,7 +1152,7 @@ ASTPointer Parser::parseInlineAssembly(ASTPointer con SourceLocation location{position(), -1, source()}; expectToken(Token::Assembly); - yul::Dialect const& dialect = yul::EVMDialect::looseAssemblyForEVM(m_evmVersion); + yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion); if (m_scanner->currentToken() == Token::StringLiteral) { if (m_scanner->currentLiteral() != "evmasm") From 5e8d348f6639cb04db2d80bbbc14cb3d68cca161 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Tue, 10 Sep 2019 10:55:39 +0200 Subject: [PATCH 051/283] Assembly: Remove StackAssignment instruction. --- docs/assembly.rst | 2 -- libsolidity/analysis/ViewPureChecker.cpp | 1 - libyul/AsmAnalysis.cpp | 11 ----------- libyul/AsmAnalysis.h | 1 - libyul/AsmData.h | 2 -- libyul/AsmDataForward.h | 3 +-- libyul/AsmParser.cpp | 17 ----------------- libyul/AsmPrinter.cpp | 7 ------- libyul/AsmPrinter.h | 1 - libyul/AsmScopeFiller.h | 1 - libyul/backends/evm/EVMCodeTransform.cpp | 8 -------- libyul/backends/evm/EVMCodeTransform.h | 1 - libyul/backends/wasm/EWasmCodeTransform.cpp | 6 ------ libyul/backends/wasm/EWasmCodeTransform.h | 1 - libyul/optimiser/ASTCopier.cpp | 6 ------ libyul/optimiser/ASTCopier.h | 2 -- libyul/optimiser/ASTWalker.h | 2 -- libyul/optimiser/SyntacticalEquality.cpp | 5 ----- libyul/optimiser/SyntacticalEquality.h | 1 - 19 files changed, 1 insertion(+), 77 deletions(-) diff --git a/docs/assembly.rst b/docs/assembly.rst index d735b54cd619..dc53716991e3 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -763,7 +763,6 @@ Grammar:: AssemblyExpression | AssemblyLocalDefinition | AssemblyAssignment | - AssemblyStackAssignment | LabelDefinition | AssemblyIf | AssemblySwitch | @@ -780,7 +779,6 @@ Grammar:: AssemblyAssignment = IdentifierOrList ':=' AssemblyExpression IdentifierOrList = Identifier | '(' IdentifierList ')' IdentifierList = Identifier ( ',' Identifier)* - AssemblyStackAssignment = '=:' Identifier LabelDefinition = Identifier ':' AssemblyIf = 'if' AssemblyExpression AssemblyBlock AssemblySwitch = 'switch' AssemblyExpression AssemblyCase* diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index 7ead355e1f26..d7efcc5e4e72 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -58,7 +58,6 @@ class AssemblyViewPureChecker: public boost::static_visitor { boost::apply_visitor(*this, _expr.expression); } - void operator()(yul::StackAssignment const&) {} void operator()(yul::Assignment const& _assignment) { boost::apply_visitor(*this, *_assignment.value); diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 9c62737d8bc1..b08b884de374 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -232,17 +232,6 @@ bool AsmAnalyzer::operator()(ExpressionStatement const& _statement) return success; } -bool AsmAnalyzer::operator()(StackAssignment const& _assignment) -{ - checkLooseFeature( - _assignment.location, - "The use of stack assignment is disallowed. Please use assignment in functional notation instead." - ); - bool success = checkAssignment(_assignment.variableName, size_t(-1)); - m_info.stackHeightInfo[&_assignment] = m_stackHeight; - return success; -} - bool AsmAnalyzer::operator()(Assignment const& _assignment) { solAssert(_assignment.value, ""); diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index facae9187b86..df30631fe4af 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -87,7 +87,6 @@ class AsmAnalyzer: public boost::static_visitor bool operator()(FunctionalInstruction const& _functionalInstruction); bool operator()(Label const& _label); bool operator()(ExpressionStatement const&); - bool operator()(StackAssignment const&); bool operator()(Assignment const& _assignment); bool operator()(VariableDeclaration const& _variableDeclaration); bool operator()(FunctionDefinition const& _functionDefinition); diff --git a/libyul/AsmData.h b/libyul/AsmData.h index cedff110689b..adfa9331e878 100644 --- a/libyul/AsmData.h +++ b/libyul/AsmData.h @@ -51,8 +51,6 @@ struct Literal { langutil::SourceLocation location; LiteralKind kind; YulString struct Identifier { langutil::SourceLocation location; YulString name; }; /// Jump label ("name:") struct Label { langutil::SourceLocation location; YulString name; }; -/// Assignment from stack (":= x", moves stack top into x, potentially multiple slots) -struct StackAssignment { langutil::SourceLocation location; Identifier variableName; }; /// Assignment ("x := mload(20:u256)", expects push-1-expression on the right hand /// side and requires x to occupy exactly one stack slot. /// diff --git a/libyul/AsmDataForward.h b/libyul/AsmDataForward.h index d01b1dffad22..feb0e0724fb4 100644 --- a/libyul/AsmDataForward.h +++ b/libyul/AsmDataForward.h @@ -30,7 +30,6 @@ namespace yul struct Instruction; struct Literal; struct Label; -struct StackAssignment; struct Identifier; struct Assignment; struct VariableDeclaration; @@ -49,6 +48,6 @@ struct Block; struct TypedName; using Expression = boost::variant; -using Statement = boost::variant; +using Statement = boost::variant; } diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index ae3056f218e3..c8484314a7a6 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -144,23 +144,6 @@ Statement Parser::parseStatement() m_scanner->next(); return stmt; } - case Token::Assign: - { - if (m_dialect.flavour != AsmFlavour::Loose) - break; - StackAssignment assignment = createWithLocation(); - advance(); - expectToken(Token::Colon); - assignment.variableName.location = location(); - assignment.variableName.name = YulString(currentLiteral()); - if (m_dialect.builtin(assignment.variableName.name)) - fatalParserError("Identifier expected, got builtin symbol."); - else if (instructions().count(assignment.variableName.name.str())) - fatalParserError("Identifier expected, got instruction name."); - assignment.location.end = endPosition(); - expectToken(Token::Identifier); - return Statement{move(assignment)}; - } default: break; } diff --git a/libyul/AsmPrinter.cpp b/libyul/AsmPrinter.cpp index 71151a0cf8ca..580e8544c850 100644 --- a/libyul/AsmPrinter.cpp +++ b/libyul/AsmPrinter.cpp @@ -120,13 +120,6 @@ string AsmPrinter::operator()(Label const& _label) const return _label.name.str() + ":"; } -string AsmPrinter::operator()(StackAssignment const& _assignment) const -{ - solAssert(!m_yul, ""); - solAssert(!_assignment.variableName.name.empty(), "Invalid variable name."); - return "=: " + (*this)(_assignment.variableName); -} - string AsmPrinter::operator()(Assignment const& _assignment) const { solAssert(_assignment.variableNames.size() >= 1, ""); diff --git a/libyul/AsmPrinter.h b/libyul/AsmPrinter.h index 82fed24f2c5c..7c6bcbc7060d 100644 --- a/libyul/AsmPrinter.h +++ b/libyul/AsmPrinter.h @@ -42,7 +42,6 @@ class AsmPrinter: public boost::static_visitor std::string operator()(FunctionalInstruction const& _functionalInstruction) const; std::string operator()(ExpressionStatement const& _expr) const; std::string operator()(Label const& _label) const; - std::string operator()(StackAssignment const& _assignment) const; std::string operator()(Assignment const& _assignment) const; std::string operator()(VariableDeclaration const& _variableDeclaration) const; std::string operator()(FunctionDefinition const& _functionDefinition) const; diff --git a/libyul/AsmScopeFiller.h b/libyul/AsmScopeFiller.h index 220538bb203a..8b1807398ea3 100644 --- a/libyul/AsmScopeFiller.h +++ b/libyul/AsmScopeFiller.h @@ -55,7 +55,6 @@ class ScopeFiller: public boost::static_visitor bool operator()(FunctionalInstruction const&) { return true; } bool operator()(ExpressionStatement const& _expr); bool operator()(Label const& _label); - bool operator()(StackAssignment const&) { return true; } bool operator()(Assignment const&) { return true; } bool operator()(VariableDeclaration const& _variableDeclaration); bool operator()(FunctionDefinition const& _functionDefinition); diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index 9ca079f07d76..64f26eb1d8a2 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -250,14 +250,6 @@ void CodeTransform::operator()(Assignment const& _assignment) checkStackHeight(&_assignment); } -void CodeTransform::operator()(StackAssignment const& _assignment) -{ - solAssert(!m_allowStackOpt, ""); - m_assembly.setSourceLocation(_assignment.location); - generateAssignment(_assignment.variableName); - checkStackHeight(&_assignment); -} - void CodeTransform::operator()(ExpressionStatement const& _statement) { m_assembly.setSourceLocation(_statement.location); diff --git a/libyul/backends/evm/EVMCodeTransform.h b/libyul/backends/evm/EVMCodeTransform.h index 866322d2db26..715aa28ee12e 100644 --- a/libyul/backends/evm/EVMCodeTransform.h +++ b/libyul/backends/evm/EVMCodeTransform.h @@ -178,7 +178,6 @@ class CodeTransform: public boost::static_visitor<> void operator()(FunctionCall const&); void operator()(ExpressionStatement const& _statement); void operator()(Label const& _label); - void operator()(StackAssignment const& _assignment); void operator()(Assignment const& _assignment); void operator()(VariableDeclaration const& _varDecl); void operator()(If const& _if); diff --git a/libyul/backends/wasm/EWasmCodeTransform.cpp b/libyul/backends/wasm/EWasmCodeTransform.cpp index f9e28e94a8dc..de089df36482 100644 --- a/libyul/backends/wasm/EWasmCodeTransform.cpp +++ b/libyul/backends/wasm/EWasmCodeTransform.cpp @@ -108,12 +108,6 @@ wasm::Expression EWasmCodeTransform::operator()(Assignment const& _assignment) return generateMultiAssignment(move(variableNames), visit(*_assignment.value)); } -wasm::Expression EWasmCodeTransform::operator()(StackAssignment const&) -{ - yulAssert(false, ""); - return {}; -} - wasm::Expression EWasmCodeTransform::operator()(ExpressionStatement const& _statement) { return visitReturnByValue(_statement.expression); diff --git a/libyul/backends/wasm/EWasmCodeTransform.h b/libyul/backends/wasm/EWasmCodeTransform.h index bbe0e1b69d18..c20ef89eabbc 100644 --- a/libyul/backends/wasm/EWasmCodeTransform.h +++ b/libyul/backends/wasm/EWasmCodeTransform.h @@ -45,7 +45,6 @@ class EWasmCodeTransform: public boost::static_visitor wasm::Expression operator()(yul::FunctionCall const&); wasm::Expression operator()(yul::ExpressionStatement const& _statement); wasm::Expression operator()(yul::Label const& _label); - wasm::Expression operator()(yul::StackAssignment const& _assignment); wasm::Expression operator()(yul::Assignment const& _assignment); wasm::Expression operator()(yul::VariableDeclaration const& _varDecl); wasm::Expression operator()(yul::If const& _if); diff --git a/libyul/optimiser/ASTCopier.cpp b/libyul/optimiser/ASTCopier.cpp index efe3ff8540f4..085efe6c3fb1 100644 --- a/libyul/optimiser/ASTCopier.cpp +++ b/libyul/optimiser/ASTCopier.cpp @@ -59,12 +59,6 @@ Statement ASTCopier::operator()(Assignment const& _assignment) }; } -Statement ASTCopier::operator()(StackAssignment const&) -{ - assertThrow(false, OptimizerException, "Invalid operation."); - return {}; -} - Statement ASTCopier::operator()(Label const&) { assertThrow(false, OptimizerException, "Invalid operation."); diff --git a/libyul/optimiser/ASTCopier.h b/libyul/optimiser/ASTCopier.h index b2e0a383a650..2ba9727a529f 100644 --- a/libyul/optimiser/ASTCopier.h +++ b/libyul/optimiser/ASTCopier.h @@ -51,7 +51,6 @@ class StatementCopier: public boost::static_visitor virtual Statement operator()(ExpressionStatement const& _statement) = 0; virtual Statement operator()(Instruction const& _instruction) = 0; virtual Statement operator()(Label const& _label) = 0; - virtual Statement operator()(StackAssignment const& _assignment) = 0; virtual Statement operator()(Assignment const& _assignment) = 0; virtual Statement operator()(VariableDeclaration const& _varDecl) = 0; virtual Statement operator()(If const& _if) = 0; @@ -78,7 +77,6 @@ class ASTCopier: public ExpressionCopier, public StatementCopier Expression operator()(FunctionCall const&) override; Statement operator()(ExpressionStatement const& _statement) override; Statement operator()(Label const& _label) override; - Statement operator()(StackAssignment const& _assignment) override; Statement operator()(Assignment const& _assignment) override; Statement operator()(VariableDeclaration const& _varDecl) override; Statement operator()(If const& _if) override; diff --git a/libyul/optimiser/ASTWalker.h b/libyul/optimiser/ASTWalker.h index a1f24479584c..4e4968556714 100644 --- a/libyul/optimiser/ASTWalker.h +++ b/libyul/optimiser/ASTWalker.h @@ -49,7 +49,6 @@ class ASTWalker: public boost::static_visitor<> virtual void operator()(FunctionCall const& _funCall); virtual void operator()(ExpressionStatement const& _statement); virtual void operator()(Label const&) { assertThrow(false, OptimizerException, ""); } - virtual void operator()(StackAssignment const&) { assertThrow(false, OptimizerException, ""); } virtual void operator()(Assignment const& _assignment); virtual void operator()(VariableDeclaration const& _varDecl); virtual void operator()(If const& _if); @@ -86,7 +85,6 @@ class ASTModifier: public boost::static_visitor<> virtual void operator()(FunctionCall& _funCall); virtual void operator()(ExpressionStatement& _statement); virtual void operator()(Label&) { assertThrow(false, OptimizerException, ""); } - virtual void operator()(StackAssignment&) { assertThrow(false, OptimizerException, ""); } virtual void operator()(Assignment& _assignment); virtual void operator()(VariableDeclaration& _varDecl); virtual void operator()(If& _if); diff --git a/libyul/optimiser/SyntacticalEquality.cpp b/libyul/optimiser/SyntacticalEquality.cpp index 9e425b17e483..e3bd8bf4f0d5 100644 --- a/libyul/optimiser/SyntacticalEquality.cpp +++ b/libyul/optimiser/SyntacticalEquality.cpp @@ -169,11 +169,6 @@ bool SyntacticallyEqual::statementEqual(Label const&, Label const&) assertThrow(false, OptimizerException, ""); } -bool SyntacticallyEqual::statementEqual(StackAssignment const&, StackAssignment const&) -{ - assertThrow(false, OptimizerException, ""); -} - bool SyntacticallyEqual::statementEqual(Block const& _lhs, Block const& _rhs) { return containerEqual(_lhs.statements, _rhs.statements, [this](Statement const& _lhsStmt, Statement const& _rhsStmt) -> bool { diff --git a/libyul/optimiser/SyntacticalEquality.h b/libyul/optimiser/SyntacticalEquality.h index c5e722c74b8d..117ce54a97d7 100644 --- a/libyul/optimiser/SyntacticalEquality.h +++ b/libyul/optimiser/SyntacticalEquality.h @@ -61,7 +61,6 @@ class SyntacticallyEqual private: bool statementEqual(Instruction const& _lhs, Instruction const& _rhs); bool statementEqual(Label const& _lhs, Label const& _rhs); - bool statementEqual(StackAssignment const& _lhs, StackAssignment const& _rhs); bool visitDeclaration(TypedName const& _lhs, TypedName const& _rhs); From e23998fc6ed1ee832d72a450f0a5d602a504a479 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Tue, 10 Sep 2019 11:15:21 +0200 Subject: [PATCH 052/283] Assembly: Remove Label instruction. --- docs/assembly.rst | 2 -- libsolidity/analysis/ViewPureChecker.cpp | 1 - libyul/AsmAnalysis.cpp | 12 ------------ libyul/AsmAnalysis.h | 1 - libyul/AsmData.h | 2 -- libyul/AsmDataForward.h | 2 +- libyul/AsmParser.cpp | 17 ----------------- libyul/AsmPrinter.cpp | 7 ------- libyul/AsmPrinter.h | 1 - libyul/AsmScopeFiller.cpp | 14 -------------- libyul/AsmScopeFiller.h | 1 - libyul/backends/evm/EVMCodeTransform.cpp | 11 ----------- libyul/backends/evm/EVMCodeTransform.h | 1 - libyul/backends/wasm/EWasmCodeTransform.cpp | 6 ------ libyul/backends/wasm/EWasmCodeTransform.h | 1 - libyul/optimiser/ASTCopier.cpp | 6 ------ libyul/optimiser/ASTCopier.h | 2 -- libyul/optimiser/ASTWalker.h | 2 -- libyul/optimiser/SyntacticalEquality.cpp | 5 ----- libyul/optimiser/SyntacticalEquality.h | 1 - 20 files changed, 1 insertion(+), 94 deletions(-) diff --git a/docs/assembly.rst b/docs/assembly.rst index dc53716991e3..6eaa7d37b7db 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -763,7 +763,6 @@ Grammar:: AssemblyExpression | AssemblyLocalDefinition | AssemblyAssignment | - LabelDefinition | AssemblyIf | AssemblySwitch | AssemblyFunctionDefinition | @@ -779,7 +778,6 @@ Grammar:: AssemblyAssignment = IdentifierOrList ':=' AssemblyExpression IdentifierOrList = Identifier | '(' IdentifierList ')' IdentifierList = Identifier ( ',' Identifier)* - LabelDefinition = Identifier ':' AssemblyIf = 'if' AssemblyExpression AssemblyBlock AssemblySwitch = 'switch' AssemblyExpression AssemblyCase* ( 'default' AssemblyBlock )? diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index d7efcc5e4e72..6d644aa4de91 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -41,7 +41,6 @@ class AssemblyViewPureChecker: public boost::static_visitor m_dialect(_dialect), m_reportMutability(_reportMutability) {} - void operator()(yul::Label const&) { } void operator()(yul::Instruction const& _instruction) { checkInstruction(_instruction.location, _instruction.instruction); diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index b08b884de374..3135693b5ae8 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -87,18 +87,6 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect, return analysisInfo; } -bool AsmAnalyzer::operator()(Label const& _label) -{ - solAssert(!_label.name.empty(), ""); - checkLooseFeature( - _label.location, - "The use of labels is disallowed. Please use \"if\", \"switch\", \"for\" or function calls instead." - ); - m_info.stackHeightInfo[&_label] = m_stackHeight; - warnOnInstructions(dev::eth::Instruction::JUMPDEST, _label.location); - return true; -} - bool AsmAnalyzer::operator()(yul::Instruction const& _instruction) { checkLooseFeature( diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index df30631fe4af..db11b47bdf06 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -85,7 +85,6 @@ class AsmAnalyzer: public boost::static_visitor bool operator()(Literal const& _literal); bool operator()(Identifier const&); bool operator()(FunctionalInstruction const& _functionalInstruction); - bool operator()(Label const& _label); bool operator()(ExpressionStatement const&); bool operator()(Assignment const& _assignment); bool operator()(VariableDeclaration const& _variableDeclaration); diff --git a/libyul/AsmData.h b/libyul/AsmData.h index adfa9331e878..e29bf8ef69f4 100644 --- a/libyul/AsmData.h +++ b/libyul/AsmData.h @@ -49,8 +49,6 @@ enum class LiteralKind { Number, Boolean, String }; struct Literal { langutil::SourceLocation location; LiteralKind kind; YulString value; Type type; }; /// External / internal identifier or label reference struct Identifier { langutil::SourceLocation location; YulString name; }; -/// Jump label ("name:") -struct Label { langutil::SourceLocation location; YulString name; }; /// Assignment ("x := mload(20:u256)", expects push-1-expression on the right hand /// side and requires x to occupy exactly one stack slot. /// diff --git a/libyul/AsmDataForward.h b/libyul/AsmDataForward.h index feb0e0724fb4..abfbf4a47a20 100644 --- a/libyul/AsmDataForward.h +++ b/libyul/AsmDataForward.h @@ -48,6 +48,6 @@ struct Block; struct TypedName; using Expression = boost::variant; -using Statement = boost::variant; +using Statement = boost::variant; } diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index c8484314a7a6..370a39c56027 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -205,23 +205,6 @@ Statement Parser::parseStatement() return Statement{std::move(assignment)}; } - case Token::Colon: - { - if (elementary.type() != typeid(Identifier)) - fatalParserError("Label name must precede \":\"."); - - Identifier const& identifier = boost::get(elementary); - - advance(); - - // label - if (m_dialect.flavour != AsmFlavour::Loose) - fatalParserError("Labels are not supported."); - - Label label = createWithLocation