aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/analysis/TypeChecker.cpp32
-rw-r--r--libsolidity/ast/Types.cpp19
-rw-r--r--libsolidity/ast/Types.h13
-rw-r--r--libsolidity/codegen/CompilerContext.cpp4
-rw-r--r--libsolidity/interface/SourceReferenceFormatter.cpp136
-rw-r--r--libsolidity/interface/SourceReferenceFormatter.h83
-rw-r--r--libsolidity/interface/StandardCompiler.cpp2
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>