diff options
Diffstat (limited to 'libsolidity/ast')
-rw-r--r-- | libsolidity/ast/AST.h | 4 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 92 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 26 |
3 files changed, 91 insertions, 31 deletions
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 761d85fe..8fd1584d 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -540,6 +540,7 @@ public: bool _isDeclaredConst, std::vector<ASTPointer<ModifierInvocation>> const& _modifiers, ASTPointer<ParameterList> const& _returnParameters, + bool _isPayable, ASTPointer<Block> const& _body ): CallableDeclaration(_location, _name, _visibility, _parameters, _returnParameters), @@ -547,6 +548,7 @@ public: ImplementationOptional(_body != nullptr), m_isConstructor(_isConstructor), m_isDeclaredConst(_isDeclaredConst), + m_isPayable(_isPayable), m_functionModifiers(_modifiers), m_body(_body) {} @@ -556,6 +558,7 @@ public: bool isConstructor() const { return m_isConstructor; } bool isDeclaredConst() const { return m_isDeclaredConst; } + bool isPayable() const { return m_isPayable; } 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 { return *m_body; } @@ -578,6 +581,7 @@ public: private: bool m_isConstructor; bool m_isDeclaredConst; + bool m_isPayable; std::vector<ASTPointer<ModifierInvocation>> m_functionModifiers; ASTPointer<Block> m_body; }; diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index d86a2caf..a0c1626d 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -362,8 +362,8 @@ MemberList::MemberMap IntegerType::nativeMembers(ContractDefinition const*) cons if (isAddress()) return { {"balance", make_shared<IntegerType >(256)}, - {"call", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Location::Bare, true)}, - {"callcode", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Location::BareCallCode, true)}, + {"call", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Location::Bare, true, false, true)}, + {"callcode", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Location::BareCallCode, true, false, true)}, {"delegatecall", make_shared<FunctionType>(strings(), strings{"bool"}, FunctionType::Location::BareDelegateCall, true)}, {"send", make_shared<FunctionType>(strings{"uint"}, strings{"bool"}, FunctionType::Location::Send)} }; @@ -1329,16 +1329,10 @@ MemberList::MemberMap ContractType::nativeMembers(ContractDefinition const*) con return members; } -shared_ptr<FunctionType const> const& ContractType::constructorType() const +shared_ptr<FunctionType const> const& ContractType::newExpressionType() const { if (!m_constructorType) - { - FunctionDefinition const* constructor = m_contract.constructor(); - if (constructor) - m_constructorType = make_shared<FunctionType>(*constructor); - else - m_constructorType = make_shared<FunctionType>(TypePointers(), TypePointers()); - } + m_constructorType = FunctionType::newExpressionType(m_contract); return m_constructorType; } @@ -1653,6 +1647,7 @@ TypePointer TupleType::closestTemporaryType(TypePointer const& _targetType) cons FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal): m_location(_isInternal ? Location::Internal : Location::External), m_isConstant(_function.isDeclaredConst()), + m_isPayable(_function.isPayable()), m_declaration(&_function) { TypePointers params; @@ -1737,7 +1732,7 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl): swap(retParamNames, m_returnParameterNames); } -FunctionType::FunctionType(const EventDefinition& _event): +FunctionType::FunctionType(EventDefinition const& _event): m_location(Location::Event), m_isConstant(true), m_declaration(&_event) { TypePointers params; @@ -1753,6 +1748,35 @@ FunctionType::FunctionType(const EventDefinition& _event): swap(paramNames, m_parameterNames); } +FunctionTypePointer FunctionType::newExpressionType(ContractDefinition const& _contract) +{ + FunctionDefinition const* constructor = _contract.constructor(); + TypePointers parameters; + strings parameterNames; + bool payable = false; + + if (constructor) + { + for (ASTPointer<VariableDeclaration> const& var: constructor->parameters()) + { + parameterNames.push_back(var->name()); + parameters.push_back(var->annotation().type); + } + payable = constructor->isPayable(); + } + return make_shared<FunctionType>( + parameters, + TypePointers{make_shared<ContractType>(_contract)}, + parameterNames, + strings{""}, + Location::Creation, + false, + nullptr, + false, + payable + ); +} + vector<string> FunctionType::parameterNames() const { if (!bound()) @@ -1871,7 +1895,12 @@ FunctionTypePointer FunctionType::interfaceFunctionType() const if (variable && retParamTypes.empty()) return FunctionTypePointer(); - return make_shared<FunctionType>(paramTypes, retParamTypes, m_parameterNames, m_returnParameterNames, m_location, m_arbitraryParameters); + return make_shared<FunctionType>( + paramTypes, retParamTypes, + m_parameterNames, m_returnParameterNames, + m_location, m_arbitraryParameters, + m_declaration, m_isConstant, m_isPayable + ); } MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) const @@ -1889,20 +1918,25 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con { MemberList::MemberMap members; if (m_location != Location::BareDelegateCall && m_location != Location::DelegateCall) - members.push_back(MemberList::Member( - "value", - make_shared<FunctionType>( - parseElementaryTypeVector({"uint"}), - TypePointers{copyAndSetGasOrValue(false, true)}, - strings(), - strings(), - Location::SetValue, - false, - nullptr, - m_gasSet, - m_valueSet - ) - )); + { + if (m_isPayable) + members.push_back(MemberList::Member( + "value", + make_shared<FunctionType>( + parseElementaryTypeVector({"uint"}), + TypePointers{copyAndSetGasOrValue(false, true)}, + strings(), + strings(), + Location::SetValue, + false, + nullptr, + false, + false, + m_gasSet, + m_valueSet + ) + )); + } if (m_location != Location::Creation) members.push_back(MemberList::Member( "gas", @@ -1914,6 +1948,8 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con Location::SetGas, false, nullptr, + false, + false, m_gasSet, m_valueSet ) @@ -2019,6 +2055,8 @@ TypePointer FunctionType::copyAndSetGasOrValue(bool _setGas, bool _setValue) con m_location, m_arbitraryParameters, m_declaration, + m_isConstant, + m_isPayable, m_gasSet || _setGas, m_valueSet || _setValue, m_bound @@ -2064,6 +2102,8 @@ FunctionTypePointer FunctionType::asMemberFunction(bool _inLibrary, bool _bound) location, m_arbitraryParameters, m_declaration, + m_isConstant, + m_isPayable, m_gasSet, m_valueSet, _bound diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 1282e5d8..9173f39a 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -640,9 +640,8 @@ public: bool isSuper() const { return m_super; } ContractDefinition const& contractDefinition() const { return m_contract; } - /// Returns the function type of the constructor. Note that the location part of the function type - /// is not used, as this type cannot be the type of a variable or expression. - FunctionTypePointer const& constructorType() const; + /// Returns the function type of the constructor modified to return an object of the contract's type. + FunctionTypePointer const& newExpressionType() const; /// @returns the identifier of the function with the given name or Invalid256 if such a name does /// not exist. @@ -820,21 +819,32 @@ public: explicit FunctionType(VariableDeclaration const& _varDecl); /// Creates the function type of an event. explicit FunctionType(EventDefinition const& _event); + /// Function type constructor to be used for a plain type (not derived from a declaration). FunctionType( strings const& _parameterTypes, strings const& _returnParameterTypes, Location _location = Location::Internal, - bool _arbitraryParameters = false + bool _arbitraryParameters = false, + bool _constant = false, + bool _payable = false ): FunctionType( parseElementaryTypeVector(_parameterTypes), parseElementaryTypeVector(_returnParameterTypes), strings(), strings(), _location, - _arbitraryParameters + _arbitraryParameters, + nullptr, + _constant, + _payable ) { } + + /// @returns the type of the "new Contract" function, i.e. basically the constructor. + static FunctionTypePointer newExpressionType(ContractDefinition const& _contract); + + /// Detailed constructor, use with care. FunctionType( TypePointers const& _parameterTypes, TypePointers const& _returnParameterTypes, @@ -843,6 +853,8 @@ public: Location _location = Location::Internal, bool _arbitraryParameters = false, Declaration const* _declaration = nullptr, + bool _isConstant = false, + bool _isPayable = false, bool _gasSet = false, bool _valueSet = false, bool _bound = false @@ -856,6 +868,8 @@ public: m_gasSet(_gasSet), m_valueSet(_valueSet), m_bound(_bound), + m_isConstant(_isConstant), + m_isPayable(_isPayable), m_declaration(_declaration) {} @@ -905,6 +919,7 @@ public: } bool hasDeclaration() const { return !!m_declaration; } bool isConstant() const { return m_isConstant; } + bool isPayable() const { return m_isPayable; } /// @return A shared pointer of an ASTString. /// Can contain a nullptr in which case indicates absence of documentation ASTPointer<ASTString> documentation() const; @@ -942,6 +957,7 @@ private: 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; }; |