diff options
author | Alex Beregszaszi <alex@rtfs.hu> | 2017-08-14 22:36:47 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-14 22:36:47 +0800 |
commit | 0a04a35a2e02437ae038af41c947b3e829946bca (patch) | |
tree | 345679632d47ede35d47a799146e76e43afe7297 /libsolidity/ast | |
parent | 4d9790b6d5a490d30ed55b69fa117bc568fa4c64 (diff) | |
parent | a26a5f20ce46800f8deff5724b5c101bb9b5fc1d (diff) | |
download | dexon-solidity-0a04a35a2e02437ae038af41c947b3e829946bca.tar.gz dexon-solidity-0a04a35a2e02437ae038af41c947b3e829946bca.tar.zst dexon-solidity-0a04a35a2e02437ae038af41c947b3e829946bca.zip |
Merge pull request #2722 from ethereum/statemutability
Introduce state mutability (to replace const/payable)
Diffstat (limited to 'libsolidity/ast')
-rw-r--r-- | libsolidity/ast/AST.h | 28 | ||||
-rw-r--r-- | libsolidity/ast/ASTEnums.h | 52 | ||||
-rw-r--r-- | libsolidity/ast/ASTForward.h | 1 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 53 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 21 |
5 files changed, 97 insertions, 58 deletions
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index d32cf573..8a577c0c 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -28,6 +28,7 @@ #include <libsolidity/ast/Types.h> #include <libsolidity/interface/Exceptions.h> #include <libsolidity/ast/ASTAnnotations.h> +#include <libsolidity/ast/ASTEnums.h> #include <libevmasm/SourceLocation.h> #include <libevmasm/Instruction.h> @@ -584,21 +585,19 @@ public: SourceLocation const& _location, ASTPointer<ASTString> const& _name, Declaration::Visibility _visibility, + StateMutability _stateMutability, bool _isConstructor, ASTPointer<ASTString> const& _documentation, ASTPointer<ParameterList> const& _parameters, - bool _isDeclaredConst, std::vector<ASTPointer<ModifierInvocation>> const& _modifiers, ASTPointer<ParameterList> const& _returnParameters, - bool _isPayable, ASTPointer<Block> const& _body ): CallableDeclaration(_location, _name, _visibility, _parameters, _returnParameters), Documented(_documentation), ImplementationOptional(_body != nullptr), + m_stateMutability(_stateMutability), m_isConstructor(_isConstructor), - m_isDeclaredConst(_isDeclaredConst), - m_isPayable(_isPayable), m_functionModifiers(_modifiers), m_body(_body) {} @@ -606,10 +605,11 @@ public: virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; + StateMutability stateMutability() const { return m_stateMutability; } bool isConstructor() const { return m_isConstructor; } bool isFallback() const { return name().empty(); } - bool isDeclaredConst() const { return m_isDeclaredConst; } - bool isPayable() const { return m_isPayable; } + 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(); } Block const& body() const { solAssert(m_body, ""); return *m_body; } @@ -634,9 +634,8 @@ public: virtual FunctionDefinitionAnnotation& annotation() const override; private: + StateMutability m_stateMutability; bool m_isConstructor; - bool m_isDeclaredConst; - bool m_isPayable; std::vector<ASTPointer<ModifierInvocation>> m_functionModifiers; ASTPointer<Block> m_body; }; @@ -896,11 +895,10 @@ public: ASTPointer<ParameterList> const& _parameterTypes, ASTPointer<ParameterList> const& _returnTypes, Declaration::Visibility _visibility, - bool _isDeclaredConst, - bool _isPayable + StateMutability _stateMutability ): TypeName(_location), m_parameterTypes(_parameterTypes), m_returnTypes(_returnTypes), - m_visibility(_visibility), m_isDeclaredConst(_isDeclaredConst), m_isPayable(_isPayable) + m_visibility(_visibility), m_stateMutability(_stateMutability) {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; @@ -914,15 +912,15 @@ public: { return m_visibility == Declaration::Visibility::Default ? Declaration::Visibility::Internal : m_visibility; } - bool isDeclaredConst() const { return m_isDeclaredConst; } - bool isPayable() const { return m_isPayable; } + StateMutability stateMutability() const { return m_stateMutability; } + bool isDeclaredConst() const { return m_stateMutability == StateMutability::View; } + bool isPayable() const { return m_stateMutability == StateMutability::Payable; } private: ASTPointer<ParameterList> m_parameterTypes; ASTPointer<ParameterList> m_returnTypes; Declaration::Visibility m_visibility; - bool m_isDeclaredConst; - bool m_isPayable; + StateMutability m_stateMutability; }; /** diff --git a/libsolidity/ast/ASTEnums.h b/libsolidity/ast/ASTEnums.h new file mode 100644 index 00000000..f7c75878 --- /dev/null +++ b/libsolidity/ast/ASTEnums.h @@ -0,0 +1,52 @@ +/* + 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 <http://www.gnu.org/licenses/>. +*/ +/** + * @date 2017 + * Enums for AST classes. + */ + +#pragma once + +#include <libsolidity/interface/Exceptions.h> + +#include <string> + +namespace dev +{ +namespace solidity +{ + +// How a function can mutate the EVM state. +enum class StateMutability { View, NonPayable, Payable }; + +inline std::string stateMutabilityToString(StateMutability const& _stateMutability) +{ + switch(_stateMutability) + { + case StateMutability::View: + return "view"; + case StateMutability::NonPayable: + return "nonpayable"; + case StateMutability::Payable: + return "payable"; + default: + solAssert(false, "Unknown state mutability."); + } +} + +} +} diff --git a/libsolidity/ast/ASTForward.h b/libsolidity/ast/ASTForward.h index cfeeaa58..15735368 100644 --- a/libsolidity/ast/ASTForward.h +++ b/libsolidity/ast/ASTForward.h @@ -95,6 +95,5 @@ using ASTPointer = std::shared_ptr<T>; using ASTString = std::string; - } } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index a66ccda5..6c2e55f6 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -477,8 +477,8 @@ MemberList::MemberMap IntegerType::nativeMembers(ContractDefinition const*) cons if (isAddress()) return { {"balance", make_shared<IntegerType >(256)}, - {"call", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareCall, true, false, true)}, - {"callcode", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareCallCode, true, false, true)}, + {"call", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareCall, true, StateMutability::Payable)}, + {"callcode", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareCallCode, true, StateMutability::Payable)}, {"delegatecall", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Kind::BareDelegateCall, true)}, {"send", make_shared<FunctionType>(strings{"uint"}, strings{"bool"}, FunctionType::Kind::Send)}, {"transfer", make_shared<FunctionType>(strings{"uint"}, strings(), FunctionType::Kind::Transfer)} @@ -2000,8 +2000,7 @@ TypePointer TupleType::closestTemporaryType(TypePointer const& _targetType) cons FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal): m_kind(_isInternal ? Kind::Internal : Kind::External), - m_isConstant(_function.isDeclaredConst()), - m_isPayable(_isInternal ? false : _function.isPayable()), + m_stateMutability(_function.stateMutability()), m_declaration(&_function) { TypePointers params; @@ -2009,6 +2008,9 @@ FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal TypePointers retParams; vector<string> retParamNames; + if (_isInternal && m_stateMutability == StateMutability::Payable) + m_stateMutability = StateMutability::NonPayable; + params.reserve(_function.parameters().size()); paramNames.reserve(_function.parameters().size()); for (ASTPointer<VariableDeclaration> const& var: _function.parameters()) @@ -2030,7 +2032,7 @@ FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal } FunctionType::FunctionType(VariableDeclaration const& _varDecl): - m_kind(Kind::External), m_isConstant(true), m_declaration(&_varDecl) + m_kind(Kind::External), m_stateMutability(StateMutability::View), m_declaration(&_varDecl) { TypePointers paramTypes; vector<string> paramNames; @@ -2090,7 +2092,7 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl): } FunctionType::FunctionType(EventDefinition const& _event): - m_kind(Kind::Event), m_isConstant(true), m_declaration(&_event) + m_kind(Kind::Event), m_stateMutability(StateMutability::View), m_declaration(&_event) { TypePointers params; vector<string> paramNames; @@ -2107,14 +2109,10 @@ FunctionType::FunctionType(EventDefinition const& _event): FunctionType::FunctionType(FunctionTypeName const& _typeName): m_kind(_typeName.visibility() == VariableDeclaration::Visibility::External ? Kind::External : Kind::Internal), - m_isConstant(_typeName.isDeclaredConst()), - m_isPayable(_typeName.isPayable()) + m_stateMutability(_typeName.stateMutability()) { if (_typeName.isPayable()) - { solAssert(m_kind == Kind::External, "Internal payable function type used."); - solAssert(!m_isConstant, "Payable constant function"); - } for (auto const& t: _typeName.parameterTypes()) { solAssert(t->annotation().type, "Type not set for parameter."); @@ -2142,7 +2140,7 @@ FunctionTypePointer FunctionType::newExpressionType(ContractDefinition const& _c FunctionDefinition const* constructor = _contract.constructor(); TypePointers parameters; strings parameterNames; - bool payable = false; + StateMutability stateMutability = StateMutability::NonPayable; if (constructor) { @@ -2151,7 +2149,8 @@ FunctionTypePointer FunctionType::newExpressionType(ContractDefinition const& _c parameterNames.push_back(var->name()); parameters.push_back(var->annotation().type); } - payable = constructor->isPayable(); + if (constructor->isPayable()) + stateMutability = StateMutability::Payable; } return make_shared<FunctionType>( parameters, @@ -2161,8 +2160,7 @@ FunctionTypePointer FunctionType::newExpressionType(ContractDefinition const& _c Kind::Creation, false, nullptr, - false, - payable + stateMutability ); } @@ -2241,8 +2239,8 @@ bool FunctionType::operator==(Type const& _other) const FunctionType const& other = dynamic_cast<FunctionType const&>(_other); if ( m_kind != other.m_kind || - m_isConstant != other.isConstant() || - m_isPayable != other.isPayable() || + isConstant() != other.isConstant() || + isPayable() != other.isPayable() || m_parameterTypes.size() != other.m_parameterTypes.size() || m_returnParameterTypes.size() != other.m_returnParameterTypes.size() ) @@ -2304,9 +2302,9 @@ 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 (m_isConstant) + if (isConstant()) name += " constant"; - if (m_isPayable) + if (isPayable()) name += " payable"; if (m_kind == Kind::External) name += " external"; @@ -2420,8 +2418,7 @@ FunctionTypePointer FunctionType::interfaceFunctionType() const m_kind, m_arbitraryParameters, m_declaration, - m_isConstant, - m_isPayable + m_stateMutability ); } @@ -2438,7 +2435,7 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con MemberList::MemberMap members; if (m_kind != Kind::BareDelegateCall && m_kind != Kind::DelegateCall) { - if (m_isPayable) + if (isPayable()) members.push_back(MemberList::Member( "value", make_shared<FunctionType>( @@ -2449,8 +2446,7 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con Kind::SetValue, false, nullptr, - false, - false, + StateMutability::NonPayable, m_gasSet, m_valueSet ) @@ -2467,8 +2463,7 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con Kind::SetGas, false, nullptr, - false, - false, + StateMutability::NonPayable, m_gasSet, m_valueSet ) @@ -2604,8 +2599,7 @@ TypePointer FunctionType::copyAndSetGasOrValue(bool _setGas, bool _setValue) con m_kind, m_arbitraryParameters, m_declaration, - m_isConstant, - m_isPayable, + m_stateMutability, m_gasSet || _setGas, m_valueSet || _setValue, m_bound @@ -2654,8 +2648,7 @@ FunctionTypePointer FunctionType::asMemberFunction(bool _inLibrary, bool _bound) kind, m_arbitraryParameters, m_declaration, - m_isConstant, - m_isPayable, + m_stateMutability, m_gasSet, m_valueSet, _bound diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 8c9232c6..56546a82 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -24,6 +24,7 @@ #include <libsolidity/interface/Exceptions.h> #include <libsolidity/ast/ASTForward.h> +#include <libsolidity/ast/ASTEnums.h> #include <libsolidity/parsing/Token.h> #include <libdevcore/Common.h> @@ -889,8 +890,7 @@ public: strings const& _returnParameterTypes, Kind _kind = Kind::Internal, bool _arbitraryParameters = false, - bool _constant = false, - bool _payable = false + StateMutability _stateMutability = StateMutability::NonPayable ): FunctionType( parseElementaryTypeVector(_parameterTypes), parseElementaryTypeVector(_returnParameterTypes), @@ -899,8 +899,7 @@ public: _kind, _arbitraryParameters, nullptr, - _constant, - _payable + _stateMutability ) { } @@ -917,8 +916,7 @@ public: Kind _kind = Kind::Internal, bool _arbitraryParameters = false, Declaration const* _declaration = nullptr, - bool _isConstant = false, - bool _isPayable = false, + StateMutability _stateMutability = StateMutability::NonPayable, bool _gasSet = false, bool _valueSet = false, bool _bound = false @@ -928,12 +926,11 @@ public: m_parameterNames(_parameterNames), m_returnParameterNames(_returnParameterNames), m_kind(_kind), + m_stateMutability(_stateMutability), m_arbitraryParameters(_arbitraryParameters), m_gasSet(_gasSet), m_valueSet(_valueSet), m_bound(_bound), - m_isConstant(_isConstant), - m_isPayable(_isPayable), m_declaration(_declaration) { solAssert( @@ -985,6 +982,7 @@ public: /// @returns true if the ABI is used for this call (only meaningful for external calls) bool isBareCall() const; Kind const& kind() const { return m_kind; } + StateMutability stateMutability() const { return m_stateMutability; } /// @returns the external signature of this function type given the function name std::string externalSignature() const; /// @returns the external identifier of this function (the hash of the signature). @@ -995,12 +993,12 @@ public: return *m_declaration; } bool hasDeclaration() const { return !!m_declaration; } - bool isConstant() const { return m_isConstant; } + bool isConstant() const { return m_stateMutability == StateMutability::View; } /// @returns true if the the result of this function only depends on its arguments /// and it does not modify the state. /// Currently, this will only return true for internal functions like keccak and ecrecover. bool isPure() const; - bool isPayable() const { return m_isPayable; } + bool isPayable() const { return m_stateMutability == StateMutability::Payable; } /// @return A shared pointer of an ASTString. /// Can contain a nullptr in which case indicates absence of documentation ASTPointer<ASTString> documentation() const; @@ -1033,13 +1031,12 @@ private: std::vector<std::string> m_parameterNames; std::vector<std::string> m_returnParameterNames; Kind const m_kind; + StateMutability m_stateMutability = StateMutability::NonPayable; /// true if the function takes an arbitrary number of arguments of arbitrary types bool const m_arbitraryParameters = false; bool const m_gasSet = false; ///< true iff the gas value to be used is on the stack bool const m_valueSet = false; ///< true iff the value to be sent is on the stack bool const m_bound = false; ///< true iff the function is called as arg1.fun(arg2, ..., argn) - bool m_isConstant = false; - bool m_isPayable = false; Declaration const* m_declaration = nullptr; }; |