diff options
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 39 | ||||
-rw-r--r-- | libsolidity/ast/AST.h | 2 | ||||
-rw-r--r-- | libsolidity/ast/ASTJsonConverter.cpp | 6 | ||||
-rw-r--r-- | libsolidity/ast/ASTPrinter.cpp | 2 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 14 | ||||
-rw-r--r-- | test/libsolidity/ASTJSON.cpp | 2 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 12 | ||||
-rw-r--r-- | test/libsolidity/SolidityTypes.cpp | 4 |
8 files changed, 42 insertions, 39 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index ca848dd0..0764bf67 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -84,8 +84,13 @@ bool TypeChecker::visit(ContractDefinition const& _contract) { if (!function->returnParameters().empty()) m_errorReporter.typeError(function->returnParameterList()->location(), "Non-empty \"returns\" directive for constructor."); - if (function->isDeclaredConst()) - m_errorReporter.typeError(function->location(), "Constructor cannot be defined as constant."); + if (function->stateMutability() != StateMutability::NonPayable && function->stateMutability() != StateMutability::Payable) + m_errorReporter.typeError( + function->location(), + "Constructor must be payable or non-payable, but is \"" + + stateMutabilityToString(function->stateMutability()) + + "\"." + ); if (function->visibility() != FunctionDefinition::Visibility::Public && function->visibility() != FunctionDefinition::Visibility::Internal) m_errorReporter.typeError(function->location(), "Constructor must be public or internal."); } @@ -104,8 +109,13 @@ bool TypeChecker::visit(ContractDefinition const& _contract) fallbackFunction = function; if (_contract.isLibrary()) m_errorReporter.typeError(fallbackFunction->location(), "Libraries cannot have fallback functions."); - if (fallbackFunction->isDeclaredConst()) - m_errorReporter.typeError(fallbackFunction->location(), "Fallback function cannot be declared constant."); + if (function->stateMutability() != StateMutability::NonPayable && function->stateMutability() != StateMutability::Payable) + m_errorReporter.typeError( + function->location(), + "Fallback function must be payable or non-payable, but is \"" + + stateMutabilityToString(function->stateMutability()) + + "\"." + ); if (!fallbackFunction->parameters().empty()) m_errorReporter.typeError(fallbackFunction->parameterList().location(), "Fallback function cannot take parameters."); if (!fallbackFunction->returnParameters().empty()) @@ -308,17 +318,16 @@ void TypeChecker::checkFunctionOverride(FunctionDefinition const& function, Func if (function.visibility() != super.visibility()) overrideError(function, super, "Overriding function visibility differs."); - else if (function.isDeclaredConst() && !super.isDeclaredConst()) - overrideError(function, super, "Overriding function should not be declared constant."); - - else if (!function.isDeclaredConst() && super.isDeclaredConst()) - overrideError(function, super, "Overriding function should be declared constant."); - - else if (function.isPayable() && !super.isPayable()) - overrideError(function, super, "Overriding function should not be declared payable."); - - else if (!function.isPayable() && super.isPayable()) - overrideError(function, super, "Overriding function should be declared payable."); + else if (function.stateMutability() != super.stateMutability()) + overrideError( + function, + super, + "Overriding function changes state mutability from \"" + + stateMutabilityToString(super.stateMutability()) + + "\" to \"" + + stateMutabilityToString(function.stateMutability()) + + "\"." + ); else if (functionType != superType) overrideError(function, super, "Overriding function return types differ."); diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 8a577c0c..53a34d32 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -608,7 +608,6 @@ public: StateMutability stateMutability() const { return m_stateMutability; } bool isConstructor() const { return m_isConstructor; } bool isFallback() const { return name().empty(); } - bool isDeclaredConst() const { return m_stateMutability == StateMutability::View; } bool isPayable() const { return m_stateMutability == StateMutability::Payable; } std::vector<ASTPointer<ModifierInvocation>> const& modifiers() const { return m_functionModifiers; } std::vector<ASTPointer<VariableDeclaration>> const& returnParameters() const { return m_returnParameters->parameters(); } @@ -913,7 +912,6 @@ public: return m_visibility == Declaration::Visibility::Default ? Declaration::Visibility::Internal : m_visibility; } StateMutability stateMutability() const { return m_stateMutability; } - bool isDeclaredConst() const { return m_stateMutability == StateMutability::View; } bool isPayable() const { return m_stateMutability == StateMutability::Payable; } private: diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index abee55ee..3f16db23 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -323,8 +323,9 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node) { std::vector<pair<string, Json::Value>> attributes = { make_pair("name", _node.name()), - make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.isDeclaredConst()), + make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.stateMutability() == StateMutability::View), make_pair("payable", _node.isPayable()), + make_pair("statemutability", stateMutabilityToString(_node.stateMutability())), make_pair("visibility", Declaration::visibilityToString(_node.visibility())), make_pair("parameters", toJson(_node.parameterList())), make_pair("isConstructor", _node.isConstructor()), @@ -419,7 +420,8 @@ bool ASTJsonConverter::visit(FunctionTypeName const& _node) setJsonNode(_node, "FunctionTypeName", { make_pair("payable", _node.isPayable()), make_pair("visibility", Declaration::visibilityToString(_node.visibility())), - make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.isDeclaredConst()), + make_pair("statemutability", stateMutabilityToString(_node.stateMutability())), + make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.stateMutability() == StateMutability::View), make_pair("parameterTypes", toJson(*_node.parameterTypeList())), make_pair("returnParameterTypes", toJson(*_node.returnParameterTypeList())), make_pair("typeDescriptions", typePointerToJson(_node.annotation().type)) diff --git a/libsolidity/ast/ASTPrinter.cpp b/libsolidity/ast/ASTPrinter.cpp index 23eb3b64..bcb5e3b9 100644 --- a/libsolidity/ast/ASTPrinter.cpp +++ b/libsolidity/ast/ASTPrinter.cpp @@ -105,7 +105,7 @@ bool ASTPrinter::visit(FunctionDefinition const& _node) { writeLine("FunctionDefinition \"" + _node.name() + "\"" + (_node.isPublic() ? " - public" : "") + - (_node.isDeclaredConst() ? " - const" : "")); + (_node.stateMutability() == StateMutability::View ? " - const" : "")); printSourcePart(_node); return goDeeper(); } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 302f1022..e6664895 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -2215,10 +2215,7 @@ string FunctionType::identifier() const case Kind::Require: id += "require";break; default: solAssert(false, "Unknown function location."); break; } - if (isConstant()) - id += "_constant"; - if (isPayable()) - id += "_payable"; + id += "_" + stateMutabilityToString(m_stateMutability); id += identifierList(m_parameterTypes) + "returns" + identifierList(m_returnParameterTypes); if (m_gasSet) id += "gas"; @@ -2237,8 +2234,7 @@ bool FunctionType::operator==(Type const& _other) const FunctionType const& other = dynamic_cast<FunctionType const&>(_other); if ( m_kind != other.m_kind || - isConstant() != other.isConstant() || - isPayable() != other.isPayable() || + m_stateMutability != other.stateMutability() || m_parameterTypes.size() != other.m_parameterTypes.size() || m_returnParameterTypes.size() != other.m_returnParameterTypes.size() ) @@ -2300,10 +2296,8 @@ string FunctionType::toString(bool _short) const for (auto it = m_parameterTypes.begin(); it != m_parameterTypes.end(); ++it) name += (*it)->toString(_short) + (it + 1 == m_parameterTypes.end() ? "" : ","); name += ")"; - if (isConstant()) - name += " constant"; - if (isPayable()) - name += " payable"; + if (m_stateMutability != StateMutability::NonPayable) + name += " " + stateMutabilityToString(m_stateMutability); if (m_kind == Kind::External) name += " external"; if (!m_returnParameterTypes.empty()) diff --git a/test/libsolidity/ASTJSON.cpp b/test/libsolidity/ASTJSON.cpp index 4fb4f20c..31165922 100644 --- a/test/libsolidity/ASTJSON.cpp +++ b/test/libsolidity/ASTJSON.cpp @@ -221,7 +221,7 @@ BOOST_AUTO_TEST_CASE(function_type) Json::Value retval = fun["children"][1]["children"][0]; BOOST_CHECK_EQUAL(retval["name"], "VariableDeclaration"); BOOST_CHECK_EQUAL(retval["attributes"]["name"], ""); - BOOST_CHECK_EQUAL(retval["attributes"]["type"], "function () constant external returns (uint256)"); + BOOST_CHECK_EQUAL(retval["attributes"]["type"], "function () view external returns (uint256)"); funType = retval["children"][0]; BOOST_CHECK_EQUAL(funType["attributes"]["constant"], true); BOOST_CHECK_EQUAL(funType["attributes"]["payable"], false); diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 1c83e1a3..fb2686fc 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -933,7 +933,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_remove_constness) contract B { function f() constant {} } contract C is B { function f() {} } )"; - CHECK_ERROR(text, TypeError, "Overriding function should be declared constant."); + CHECK_ERROR(text, TypeError, "Overriding function changes state mutability from \"view\" to \"nonpayable\"."); } BOOST_AUTO_TEST_CASE(illegal_override_add_constness) @@ -942,7 +942,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_add_constness) contract B { function f() {} } contract C is B { function f() constant {} } )"; - CHECK_ERROR(text, TypeError, "Overriding function should not be declared constant."); + CHECK_ERROR(text, TypeError, "Overriding function changes state mutability from \"nonpayable\" to \"view\"."); } BOOST_AUTO_TEST_CASE(complex_inheritance) @@ -1363,7 +1363,7 @@ BOOST_AUTO_TEST_CASE(fallback_function_with_constant_modifier) function() constant { x = 2; } } )"; - CHECK_ERROR(text, TypeError, "Fallback function cannot be declared constant."); + CHECK_ERROR(text, TypeError, "Fallback function must be payable or non-payable"); } BOOST_AUTO_TEST_CASE(fallback_function_twice) @@ -4779,7 +4779,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_payable) contract B { function f() payable {} } contract C is B { function f() {} } )"; - CHECK_ERROR(text, TypeError, "Overriding function should be declared payable."); + CHECK_ERROR(text, TypeError, "Overriding function changes state mutability from \"payable\" to \"nonpayable\"."); } BOOST_AUTO_TEST_CASE(illegal_override_payable_nonpayable) @@ -4788,7 +4788,7 @@ BOOST_AUTO_TEST_CASE(illegal_override_payable_nonpayable) contract B { function f() {} } contract C is B { function f() payable {} } )"; - CHECK_ERROR(text, TypeError, "Overriding function should not be declared payable."); + CHECK_ERROR(text, TypeError, "Overriding function changes state mutability from \"nonpayable\" to \"payable\"."); } BOOST_AUTO_TEST_CASE(function_variable_mixin) @@ -4873,7 +4873,7 @@ BOOST_AUTO_TEST_CASE(constant_constructor) function test() constant {} } )"; - CHECK_ERROR(text, TypeError, "Constructor cannot be defined as constant."); + CHECK_ERROR(text, TypeError, "Constructor must be payable or non-payable"); } BOOST_AUTO_TEST_CASE(external_constructor) diff --git a/test/libsolidity/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp index 0b5ab516..9f385a04 100644 --- a/test/libsolidity/SolidityTypes.cpp +++ b/test/libsolidity/SolidityTypes.cpp @@ -129,10 +129,10 @@ BOOST_AUTO_TEST_CASE(type_identifiers) BOOST_CHECK_EQUAL(t.identifier(), "t_tuple$_t_type$_t_enum$_Enum_$4_$_$_t_type$_t_struct$_Struct_$3_storage_ptr_$_$_t_array$_t_string_storage_$20_storage_ptr_$__$"); TypePointer sha3fun = make_shared<FunctionType>(strings{}, strings{}, FunctionType::Kind::SHA3); - BOOST_CHECK_EQUAL(sha3fun->identifier(), "t_function_sha3$__$returns$__$"); + BOOST_CHECK_EQUAL(sha3fun->identifier(), "t_function_sha3_nonpayable$__$returns$__$"); FunctionType metaFun(TypePointers{sha3fun}, TypePointers{s.type()}); - BOOST_CHECK_EQUAL(metaFun.identifier(), "t_function_internal$_t_function_sha3$__$returns$__$_$returns$_t_type$_t_struct$_Struct_$3_storage_ptr_$_$"); + BOOST_CHECK_EQUAL(metaFun.identifier(), "t_function_internal_nonpayable$_t_function_sha3_nonpayable$__$returns$__$_$returns$_t_type$_t_struct$_Struct_$3_storage_ptr_$_$"); TypePointer m = make_shared<MappingType>(Type::fromElementaryTypeName("bytes32"), s.type()); MappingType m2(Type::fromElementaryTypeName("uint64"), m); |