This commit is contained in:
Kamil Śliwak 2023-09-29 22:06:33 +00:00 committed by GitHub
commit 01707cb182
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 100 additions and 50 deletions

View File

@ -29,6 +29,26 @@
using namespace solidity;
using namespace solidity::langutil;
std::map<Error::Type, std::string> const Error::m_errorTypeNames = {
{Error::Type::IOError, "IOError"},
{Error::Type::FatalError, "FatalError"},
{Error::Type::JSONError, "JSONError"},
{Error::Type::InternalCompilerError, "InternalCompilerError"},
{Error::Type::CompilerError, "CompilerError"},
{Error::Type::Exception, "Exception"},
{Error::Type::CodeGenerationError, "CodeGenerationError"},
{Error::Type::DeclarationError, "DeclarationError"},
{Error::Type::DocstringParsingError, "DocstringParsingError"},
{Error::Type::ParserError, "ParserError"},
{Error::Type::SyntaxError, "SyntaxError"},
{Error::Type::TypeError, "TypeError"},
{Error::Type::UnimplementedFeatureError, "UnimplementedFeatureError"},
{Error::Type::YulException, "YulException"},
{Error::Type::SMTLogicException, "SMTLogicException"},
{Error::Type::Warning, "Warning"},
{Error::Type::Info, "Info"},
};
Error::Error(
ErrorId _errorId, Error::Type _type,
std::string const& _description,

View File

@ -33,10 +33,11 @@
#include <boost/preprocessor/facilities/overload.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <optional>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <memory>
#include <variant>
namespace solidity::langutil
@ -269,27 +270,17 @@ public:
static std::string formatErrorType(Type _type)
{
switch (_type)
{
case Type::IOError: return "IOError";
case Type::FatalError: return "FatalError";
case Type::JSONError: return "JSONError";
case Type::InternalCompilerError: return "InternalCompilerError";
case Type::CompilerError: return "CompilerError";
case Type::Exception: return "Exception";
case Type::CodeGenerationError: return "CodeGenerationError";
case Type::DeclarationError: return "DeclarationError";
case Type::DocstringParsingError: return "DocstringParsingError";
case Type::ParserError: return "ParserError";
case Type::SyntaxError: return "SyntaxError";
case Type::TypeError: return "TypeError";
case Type::UnimplementedFeatureError: return "UnimplementedFeatureError";
case Type::YulException: return "YulException";
case Type::SMTLogicException: return "SMTLogicException";
case Type::Warning: return "Warning";
case Type::Info: return "Info";
}
util::unreachable();
return m_errorTypeNames.at(_type);
}
static std::optional<Type> parseErrorType(std::string _name)
{
static std::map<std::string, Error::Type> const m_errorTypesByName = util::invertMap(m_errorTypeNames);
if (m_errorTypesByName.count(_name) == 0)
return std::nullopt;
return m_errorTypesByName.at(_name);
}
static std::string formatTypeOrSeverity(std::variant<Error::Type, Error::Severity> _typeOrSeverity)
@ -309,6 +300,8 @@ public:
private:
ErrorId m_errorId;
Type m_type;
static std::map<Type, std::string> const m_errorTypeNames;
};
}

View File

@ -55,6 +55,28 @@ std::string SourceReferenceFormatter::formatErrorInformation(Error const& _error
);
}
char const* SourceReferenceFormatter::errorTextColor(Error::Severity _severity)
{
switch (_severity)
{
case Error::Severity::Error: return RED;
case Error::Severity::Warning: return YELLOW;
case Error::Severity::Info: return WHITE;
}
util::unreachable();
}
char const* SourceReferenceFormatter::errorHighlightColor(Error::Severity _severity)
{
switch (_severity)
{
case Error::Severity::Error: return RED_BACKGROUND;
case Error::Severity::Warning: return ORANGE_BACKGROUND_256;
case Error::Severity::Info: return GRAY_BACKGROUND;
}
util::unreachable();
}
AnsiColorized SourceReferenceFormatter::normalColored() const
{
return AnsiColorized(m_stream, m_colored, {WHITE});
@ -67,18 +89,7 @@ AnsiColorized SourceReferenceFormatter::frameColored() const
AnsiColorized SourceReferenceFormatter::errorColored(Error::Severity _severity) const
{
// We used to color messages of any severity as errors so this seems like a good default
// for cases where severity cannot be determined.
char const* textColor = RED;
switch (_severity)
{
case Error::Severity::Error: textColor = RED; break;
case Error::Severity::Warning: textColor = YELLOW; break;
case Error::Severity::Info: textColor = WHITE; break;
}
return AnsiColorized(m_stream, m_colored, {BOLD, textColor});
return AnsiColorized(m_stream, m_colored, {BOLD, errorTextColor(_severity)});
}
AnsiColorized SourceReferenceFormatter::messageColored() const

View File

@ -118,6 +118,15 @@ public:
static std::string formatErrorInformation(Error const& _error, CharStream const& _charStream);
/// The default text color for printing error messages of a given severity in the terminal.
/// Only suitable for color schemes with a dark background.
static char const* errorTextColor(Error::Severity _severity);
/// The default background color for highlighting source fragments corresponding to an error
/// of a given severity in the terminal.
/// Only suitable for color schemes with a light text.
static char const* errorHighlightColor(Error::Severity _severity);
private:
util::AnsiColorized normalColored() const;
util::AnsiColorized frameColored() const;

View File

@ -52,6 +52,7 @@ static constexpr char const* BLUE_BACKGROUND = "\033[44m";
static constexpr char const* MAGENTA_BACKGROUND = "\033[45m";
static constexpr char const* CYAN_BACKGROUND = "\033[46m";
static constexpr char const* WHITE_BACKGROUND = "\033[47m";
static constexpr char const* GRAY_BACKGROUND = "\033[100m";
// 256-bit-colors (incomplete set)
static constexpr char const* RED_BACKGROUND_256 = "\033[48;5;160m";

View File

@ -19,11 +19,16 @@
#include <test/CommonSyntaxTest.h>
#include <test/Common.h>
#include <test/TestCase.h>
#include <liblangutil/SourceReferenceFormatter.h>
#include <libsolutil/CommonIO.h>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/throw_exception.hpp>
#include <fstream>
#include <memory>
#include <stdexcept>
@ -114,15 +119,18 @@ void CommonSyntaxTest::printSource(ostream& _stream, string const& _linePrefix,
{
assert(static_cast<size_t>(error.locationStart) <= source.length());
assert(static_cast<size_t>(error.locationEnd) <= source.length());
bool isWarning = error.type == "Warning";
for (int i = error.locationStart; i < error.locationEnd; i++)
if (isWarning)
{
if (sourceFormatting[static_cast<size_t>(i)] == util::formatting::RESET)
sourceFormatting[static_cast<size_t>(i)] = util::formatting::ORANGE_BACKGROUND_256;
}
else
sourceFormatting[static_cast<size_t>(i)] = util::formatting::RED_BACKGROUND;
{
char const*& cellFormat = sourceFormatting[static_cast<size_t>(i)];
char const* infoBgColor = SourceReferenceFormatter::errorHighlightColor(Error::Severity::Info);
if (
(error.type != Error::Type::Warning && error.type != Error::Type::Info) ||
(error.type == Error::Type::Warning && (cellFormat == RESET || cellFormat == infoBgColor)) ||
(error.type == Error::Type::Info && cellFormat == RESET)
)
cellFormat = SourceReferenceFormatter::errorHighlightColor(Error::errorSeverity(error.type));
}
}
_stream << _linePrefix << sourceFormatting.front() << source.front();
@ -192,8 +200,12 @@ void CommonSyntaxTest::printErrorList(
for (auto const& error: _errorList)
{
{
util::AnsiColorized scope(_stream, _formatted, {BOLD, (error.type == "Warning") ? YELLOW : RED});
_stream << _linePrefix << error.type;
util::AnsiColorized scope(
_stream,
_formatted,
{BOLD, SourceReferenceFormatter::errorTextColor(Error::errorSeverity(error.type))}
);
_stream << _linePrefix << Error::formatErrorType(error.type);
if (error.errorId.has_value())
_stream << ' ' << error.errorId->error;
_stream << ": ";
@ -246,7 +258,11 @@ vector<SyntaxTestError> CommonSyntaxTest::parseExpectations(istream& _stream)
auto typeBegin = it;
while (it != line.end() && isalpha(*it, locale::classic()))
++it;
string errorType(typeBegin, it);
std::string errorTypeStr(typeBegin, it);
optional<Error::Type> errorType = Error::parseErrorType(errorTypeStr);
if (!errorType.has_value())
BOOST_THROW_EXCEPTION(runtime_error("Invalid error type: " + errorTypeStr));
skipWhitespace(it, line.end());
@ -283,7 +299,7 @@ vector<SyntaxTestError> CommonSyntaxTest::parseExpectations(istream& _stream)
string errorMessage(it, line.end());
expectations.emplace_back(SyntaxTestError{
std::move(errorType),
errorType.value(),
std::move(errorId),
std::move(errorMessage),
std::move(sourceName),

View File

@ -34,7 +34,7 @@ namespace solidity::test
struct SyntaxTestError
{
std::string type;
langutil::Error::Type type;
std::optional<langutil::ErrorId> errorId;
std::string message;
std::string sourceName;

View File

@ -86,7 +86,7 @@ void SyntaxTest::parseAndAnalyze()
catch (UnimplementedFeatureError const& _e)
{
m_errorList.emplace_back(SyntaxTestError{
"UnimplementedFeatureError",
Error::Type::UnimplementedFeatureError,
nullopt,
errorMessage(_e),
"",
@ -135,7 +135,7 @@ void SyntaxTest::filterObtainedErrors()
}
}
m_errorList.emplace_back(SyntaxTestError{
Error::formatErrorType(currentError->type()),
currentError->type(),
currentError->errorId(),
errorMessage(*currentError),
sourceName,

View File

@ -61,7 +61,7 @@ void SyntaxTest::parseAndAnalyze()
}
m_errorList.emplace_back(SyntaxTestError{
Error::formatErrorType(error->type()),
error->type(),
error->errorId(),
errorMessage(*error),
name,