From aeb66905de3f65ca7a63addb6c9d05108986dbeb Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Sat, 24 Nov 2018 12:33:36 +0100 Subject: Moving SourceReferenceFormatter into langutil namespace. --- liblangutil/SourceReferenceFormatter.cpp | 129 +++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 liblangutil/SourceReferenceFormatter.cpp (limited to 'liblangutil/SourceReferenceFormatter.cpp') diff --git a/liblangutil/SourceReferenceFormatter.cpp b/liblangutil/SourceReferenceFormatter.cpp new file mode 100644 index 00000000..58a65521 --- /dev/null +++ b/liblangutil/SourceReferenceFormatter.cpp @@ -0,0 +1,129 @@ +/* + 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 . +*/ +/** + * @author Christian + * @date 2014 + * Formatting functions for errors referencing positions and locations in the source. + */ + +#include +#include +#include + +using namespace std; +using namespace dev; +using namespace langutil; + +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( + dev::Exception const& _exception, + string const& _name +) +{ + SourceLocation const* location = boost::get_error_info(_exception); + auto secondarylocation = boost::get_error_info(_exception); + + printSourceName(location); + + m_stream << _name; + if (string const* description = boost::get_error_info(_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; + } +} -- cgit v1.2.3 From c48a5264be4221873fe02cac57f6a41a32010fea Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Wed, 28 Nov 2018 16:19:22 +0100 Subject: liblangutil: SourceLocation: adds (shared) pointer to underlying CharStream source, eliminating sourceName Also, adapted affecting code to those changes. --- liblangutil/SourceReferenceFormatter.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'liblangutil/SourceReferenceFormatter.cpp') diff --git a/liblangutil/SourceReferenceFormatter.cpp b/liblangutil/SourceReferenceFormatter.cpp index 58a65521..8ac05b4e 100644 --- a/liblangutil/SourceReferenceFormatter.cpp +++ b/liblangutil/SourceReferenceFormatter.cpp @@ -30,9 +30,9 @@ using namespace langutil; void SourceReferenceFormatter::printSourceLocation(SourceLocation const* _location) { - if (!_location || !_location->sourceName) + if (!_location || !_location->source) return; // Nothing we can print here - auto const& scanner = m_scannerFromSourceName(*_location->sourceName); + auto const& scanner = m_scannerFromSourceName(_location->source->name()); int startLine; int startColumn; tie(startLine, startColumn) = scanner.translatePositionToLineColumn(_location->start); @@ -89,13 +89,13 @@ void SourceReferenceFormatter::printSourceLocation(SourceLocation const* _locati void SourceReferenceFormatter::printSourceName(SourceLocation const* _location) { - if (!_location || !_location->sourceName) + if (!_location || !_location->source) return; // Nothing we can print here - auto const& scanner = m_scannerFromSourceName(*_location->sourceName); + auto const& scanner = m_scannerFromSourceName(_location->source->name()); int startLine; int startColumn; tie(startLine, startColumn) = scanner.translatePositionToLineColumn(_location->start); - m_stream << *_location->sourceName << ":" << (startLine + 1) << ":" << (startColumn + 1) << ": "; + m_stream << _location->source->name() << ":" << (startLine + 1) << ":" << (startColumn + 1) << ": "; } void SourceReferenceFormatter::printExceptionInformation( -- cgit v1.2.3