diff options
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 32 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 19 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 13 | ||||
-rw-r--r-- | libsolidity/codegen/CompilerContext.cpp | 4 | ||||
-rw-r--r-- | libsolidity/interface/SourceReferenceFormatter.cpp | 136 | ||||
-rw-r--r-- | libsolidity/interface/SourceReferenceFormatter.h | 83 | ||||
-rw-r--r-- | libsolidity/interface/StandardCompiler.cpp | 2 |
7 files changed, 35 insertions, 254 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 4e63875b..a6c23ada 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -400,42 +400,42 @@ void TypeChecker::checkContractIllegalOverrides(ContractDefinition const& _contr } } -void TypeChecker::checkFunctionOverride(FunctionDefinition const& function, FunctionDefinition const& super) +void TypeChecker::checkFunctionOverride(FunctionDefinition const& _function, FunctionDefinition const& _super) { - FunctionType functionType(function); - FunctionType superType(super); + FunctionType functionType(_function); + FunctionType superType(_super); if (!functionType.hasEqualParameterTypes(superType)) return; - if (!function.annotation().superFunction) - function.annotation().superFunction = &super; + if (!_function.annotation().superFunction) + _function.annotation().superFunction = &_super; - if (function.visibility() != super.visibility()) + if (_function.visibility() != _super.visibility()) { // visibility is enforced to be external in interfaces, but a contract can override that with public if ( - super.inContractKind() == ContractDefinition::ContractKind::Interface && - function.inContractKind() != ContractDefinition::ContractKind::Interface && - function.visibility() == FunctionDefinition::Visibility::Public + _super.inContractKind() == ContractDefinition::ContractKind::Interface && + _function.inContractKind() != ContractDefinition::ContractKind::Interface && + _function.visibility() == FunctionDefinition::Visibility::Public ) return; - overrideError(function, super, "Overriding function visibility differs."); + overrideError(_function, _super, "Overriding function visibility differs."); } - else if (function.stateMutability() != super.stateMutability()) + else if (_function.stateMutability() != _super.stateMutability()) overrideError( - function, - super, + _function, + _super, "Overriding function changes state mutability from \"" + - stateMutabilityToString(super.stateMutability()) + + stateMutabilityToString(_super.stateMutability()) + "\" to \"" + - stateMutabilityToString(function.stateMutability()) + + stateMutabilityToString(_function.stateMutability()) + "\"." ); else if (functionType != superType) - overrideError(function, super, "Overriding function return types differ."); + overrideError(_function, _super, "Overriding function return types differ."); } void TypeChecker::overrideError(FunctionDefinition const& function, FunctionDefinition const& super, string message) diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 0eab75aa..102e43e9 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -442,10 +442,11 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ContractDefinition if (!function->isVisibleAsLibraryMember() || seenFunctions.count(function)) continue; seenFunctions.insert(function); - FunctionType funType(*function, false); - if (auto fun = funType.asMemberFunction(true, true)) - if (_type.isImplicitlyConvertibleTo(*fun->selfType())) - members.push_back(MemberList::Member(function->name(), fun, function)); + if (function->parameters().empty()) + continue; + FunctionTypePointer fun = FunctionType(*function, false).asCallableFunction(true, true); + if (_type.isImplicitlyConvertibleTo(*fun->selfType())) + members.push_back(MemberList::Member(function->name(), fun, function)); } } return members; @@ -1970,7 +1971,7 @@ MemberList::MemberMap ContractType::nativeMembers(ContractDefinition const* _con for (auto const& it: m_contract.interfaceFunctions()) members.push_back(MemberList::Member( it.second->declaration().name(), - it.second->asMemberFunction(m_contract.isLibrary()), + it.second->asCallableFunction(m_contract.isLibrary()), &it.second->declaration() )); } @@ -3059,10 +3060,10 @@ TypePointer FunctionType::copyAndSetGasOrValue(bool _setGas, bool _setValue) con ); } -FunctionTypePointer FunctionType::asMemberFunction(bool _inLibrary, bool _bound) const +FunctionTypePointer FunctionType::asCallableFunction(bool _inLibrary, bool _bound) const { - if (_bound && m_parameterTypes.empty()) - return FunctionTypePointer(); + if (_bound) + solAssert(!m_parameterTypes.empty(), ""); TypePointers parameterTypes; for (auto const& t: m_parameterTypes) @@ -3201,7 +3202,7 @@ MemberList::MemberMap TypeType::nativeMembers(ContractDefinition const* _current if (function->isVisibleAsLibraryMember()) members.push_back(MemberList::Member( function->name(), - FunctionType(*function).asMemberFunction(true), + FunctionType(*function).asCallableFunction(true), function )); if (isBase) diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 482d6735..953aa557 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -1154,14 +1154,13 @@ public: /// of the parameters to false. TypePointer copyAndSetGasOrValue(bool _setGas, bool _setValue) const; - /// @returns a copy of this function type where all return parameters of dynamic size are - /// removed and the location of reference types is changed from CallData to Memory. - /// This is needed if external functions are called on other contracts, as they cannot return - /// dynamic values. - /// Returns empty shared pointer on a failure. Namely, if a bound function has no parameters. + /// @returns a copy of this function type where the location of reference types is changed + /// from CallData to Memory. This is the type that would be used when the function is + /// called, as opposed to the parameter types that are available inside the function body. + /// Also supports variants to be used for library or bound calls. /// @param _inLibrary if true, uses DelegateCall as location. - /// @param _bound if true, the arguments are placed as `arg1.functionName(arg2, ..., argn)`. - FunctionTypePointer asMemberFunction(bool _inLibrary, bool _bound = false) const; + /// @param _bound if true, the function type is set to be bound. + FunctionTypePointer asCallableFunction(bool _inLibrary, bool _bound = false) const; private: static TypePointers parseElementaryTypeVector(strings const& _types); diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index d1bf29fc..2fd62de2 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -25,7 +25,7 @@ #include <libsolidity/ast/AST.h> #include <libsolidity/codegen/Compiler.h> #include <libsolidity/interface/Version.h> -#include <libsolidity/interface/SourceReferenceFormatter.h> +#include <liblangutil/SourceReferenceFormatter.h> #include <libyul/AsmParser.h> #include <libyul/AsmCodeGen.h> #include <libyul/AsmAnalysis.h> @@ -414,7 +414,7 @@ FunctionDefinition const& CompilerContext::resolveVirtualFunction( if ( function->name() == name && !function->isConstructor() && - FunctionType(*function).hasEqualParameterTypes(functionType) + FunctionType(*function).asCallableFunction(false)->hasEqualParameterTypes(functionType) ) return *function; solAssert(false, "Super function " + name + " not found."); diff --git a/libsolidity/interface/SourceReferenceFormatter.cpp b/libsolidity/interface/SourceReferenceFormatter.cpp deleted file mode 100644 index d727afbe..00000000 --- a/libsolidity/interface/SourceReferenceFormatter.cpp +++ /dev/null @@ -1,136 +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 <http://www.gnu.org/licenses/>. -*/ -/** - * @author Christian <c@ethdev.com> - * @date 2014 - * Formatting functions for errors referencing positions and locations in the source. - */ - -#include <libsolidity/interface/SourceReferenceFormatter.h> -#include <liblangutil/Scanner.h> -#include <liblangutil/Exceptions.h> - -using namespace std; -using namespace langutil; - -namespace dev -{ -namespace solidity -{ - -void SourceReferenceFormatter::printSourceLocation(SourceLocation const* _location) -{ - if (!_location || !_location->sourceName) - return; // Nothing we can print here - auto const& scanner = m_scannerFromSourceName(*_location->sourceName); - int startLine; - int startColumn; - tie(startLine, startColumn) = scanner.translatePositionToLineColumn(_location->start); - int endLine; - int endColumn; - tie(endLine, endColumn) = scanner.translatePositionToLineColumn(_location->end); - if (startLine == endLine) - { - string line = scanner.lineAtPosition(_location->start); - - int locationLength = endColumn - startColumn; - if (locationLength > 150) - { - line = line.substr(0, startColumn + 35) + " ... " + line.substr(endColumn - 35); - endColumn = startColumn + 75; - locationLength = 75; - } - if (line.length() > 150) - { - int len = line.length(); - line = line.substr(max(0, startColumn - 35), min(startColumn, 35) + min(locationLength + 35, len - startColumn)); - if (startColumn + locationLength + 35 < len) - line += " ..."; - if (startColumn > 35) - { - line = " ... " + line; - startColumn = 40; - } - endColumn = startColumn + locationLength; - } - - m_stream << line << endl; - - for_each( - line.cbegin(), - line.cbegin() + startColumn, - [this](char const& ch) { m_stream << (ch == '\t' ? '\t' : ' '); } - ); - m_stream << "^"; - if (endColumn > startColumn + 2) - m_stream << string(endColumn - startColumn - 2, '-'); - if (endColumn > startColumn + 1) - m_stream << "^"; - m_stream << endl; - } - else - m_stream << - scanner.lineAtPosition(_location->start) << - endl << - string(startColumn, ' ') << - "^ (Relevant source part starts here and spans across multiple lines)." << - endl; -} - -void SourceReferenceFormatter::printSourceName(SourceLocation const* _location) -{ - if (!_location || !_location->sourceName) - return; // Nothing we can print here - auto const& scanner = m_scannerFromSourceName(*_location->sourceName); - int startLine; - int startColumn; - tie(startLine, startColumn) = scanner.translatePositionToLineColumn(_location->start); - m_stream << *_location->sourceName << ":" << (startLine + 1) << ":" << (startColumn + 1) << ": "; -} - -void SourceReferenceFormatter::printExceptionInformation( - Exception const& _exception, - string const& _name -) -{ - SourceLocation const* location = boost::get_error_info<errinfo_sourceLocation>(_exception); - auto secondarylocation = boost::get_error_info<errinfo_secondarySourceLocation>(_exception); - - printSourceName(location); - - m_stream << _name; - if (string const* description = boost::get_error_info<errinfo_comment>(_exception)) - m_stream << ": " << *description << endl; - else - m_stream << endl; - - printSourceLocation(location); - - if (secondarylocation && !secondarylocation->infos.empty()) - { - for (auto info: secondarylocation->infos) - { - printSourceName(&info.second); - m_stream << info.first << endl; - printSourceLocation(&info.second); - } - m_stream << endl; - } -} - -} -} diff --git a/libsolidity/interface/SourceReferenceFormatter.h b/libsolidity/interface/SourceReferenceFormatter.h deleted file mode 100644 index 7dea5254..00000000 --- a/libsolidity/interface/SourceReferenceFormatter.h +++ /dev/null @@ -1,83 +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 <http://www.gnu.org/licenses/>. -*/ -/** - * @author Christian <c@ethdev.com> - * @date 2014 - * Formatting functions for errors referencing positions and locations in the source. - */ - -#pragma once - -#include <ostream> -#include <sstream> -#include <functional> - -namespace langutil -{ -struct SourceLocation; -class Scanner; -} - -namespace dev -{ - -struct Exception; // forward - -namespace solidity -{ - -class CompilerStack; // forward - -class SourceReferenceFormatter -{ -public: - using ScannerFromSourceNameFun = std::function<langutil::Scanner const&(std::string const&)>; - - explicit SourceReferenceFormatter( - std::ostream& _stream, - ScannerFromSourceNameFun _scannerFromSourceName - ): - m_stream(_stream), - m_scannerFromSourceName(std::move(_scannerFromSourceName)) - {} - - /// Prints source location if it is given. - void printSourceLocation(langutil::SourceLocation const* _location); - void printExceptionInformation(Exception const& _exception, std::string const& _name); - - static std::string formatExceptionInformation( - Exception const& _exception, - std::string const& _name, - ScannerFromSourceNameFun const& _scannerFromSourceName - ) - { - std::ostringstream errorOutput; - - SourceReferenceFormatter formatter(errorOutput, _scannerFromSourceName); - formatter.printExceptionInformation(_exception, _name); - return errorOutput.str(); - } -private: - /// Prints source name if location is given. - void printSourceName(langutil::SourceLocation const* _location); - - std::ostream& m_stream; - ScannerFromSourceNameFun m_scannerFromSourceName; -}; - -} -} diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index bf33b789..4a32d9f3 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -21,7 +21,7 @@ */ #include <libsolidity/interface/StandardCompiler.h> -#include <libsolidity/interface/SourceReferenceFormatter.h> +#include <liblangutil/SourceReferenceFormatter.h> #include <libsolidity/ast/ASTJsonConverter.h> #include <libevmasm/Instruction.h> #include <libdevcore/JSON.h> |