mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add error IDs to console output
This commit is contained in:
parent
b17915a6ba
commit
51e64fe0b1
@ -5,7 +5,7 @@ Language Features:
|
||||
|
||||
Compiler Features:
|
||||
* Yul: Raise warning for switch statements that only have a default and no other cases.
|
||||
* Add error codes to JSON output.
|
||||
* Output compilation error codes.
|
||||
|
||||
|
||||
Bugfixes:
|
||||
|
@ -38,7 +38,15 @@ SourceReferenceExtractor::Message SourceReferenceExtractor::extract(util::Except
|
||||
for (auto const& info: secondaryLocation->infos)
|
||||
secondary.emplace_back(extract(&info.second, info.first));
|
||||
|
||||
return Message{std::move(primary), _category, std::move(secondary)};
|
||||
return Message{std::move(primary), _category, std::move(secondary), nullopt};
|
||||
}
|
||||
|
||||
SourceReferenceExtractor::Message SourceReferenceExtractor::extract(Error const& _error)
|
||||
{
|
||||
string category = (_error.type() == Error::Type::Warning) ? "Warning" : "Error";
|
||||
Message message = extract(_error, category);
|
||||
message.errorId = _error.errorId();
|
||||
return message;
|
||||
}
|
||||
|
||||
SourceReference SourceReferenceExtractor::extract(SourceLocation const* _location, std::string message)
|
||||
|
@ -16,16 +16,14 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
#include <iosfwd>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
namespace solidity::util
|
||||
{
|
||||
struct Exception;
|
||||
}
|
||||
|
||||
namespace solidity::langutil
|
||||
{
|
||||
|
||||
@ -58,8 +56,6 @@ struct SourceReference
|
||||
}
|
||||
};
|
||||
|
||||
struct SourceLocation;
|
||||
|
||||
namespace SourceReferenceExtractor
|
||||
{
|
||||
struct Message
|
||||
@ -67,9 +63,11 @@ namespace SourceReferenceExtractor
|
||||
SourceReference primary;
|
||||
std::string category; // "Error", "Warning", ...
|
||||
std::vector<SourceReference> secondary;
|
||||
std::optional<ErrorId> errorId;
|
||||
};
|
||||
|
||||
Message extract(util::Exception const& _exception, std::string _category);
|
||||
Message extract(Error const& _error);
|
||||
SourceReference extract(SourceLocation const* _location, std::string message = "");
|
||||
}
|
||||
|
||||
|
@ -80,10 +80,7 @@ void SourceReferenceFormatter::printExceptionInformation(util::Exception const&
|
||||
|
||||
void SourceReferenceFormatter::printErrorInformation(Error const& _error)
|
||||
{
|
||||
printExceptionInformation(
|
||||
_error,
|
||||
(_error.type() == Error::Type::Warning) ? "Warning" : "Error"
|
||||
);
|
||||
printExceptionInformation(SourceReferenceExtractor::extract(_error));
|
||||
}
|
||||
|
||||
void SourceReferenceFormatter::printExceptionInformation(SourceReferenceExtractor::Message const& _msg)
|
||||
|
@ -151,6 +151,8 @@ void SourceReferenceFormatterHuman::printExceptionInformation(SourceReferenceExt
|
||||
{
|
||||
// exception header line
|
||||
errorColored() << _msg.category;
|
||||
if (m_withErrorIds && _msg.errorId.has_value())
|
||||
errorColored() << " (" << _msg.errorId.value().error << ")";
|
||||
messageColored() << ": " << _msg.primary.message << '\n';
|
||||
|
||||
printSourceLocation(_msg.primary);
|
||||
|
@ -29,22 +29,14 @@
|
||||
#include <sstream>
|
||||
#include <functional>
|
||||
|
||||
namespace solidity::util
|
||||
{
|
||||
struct Exception; // forward
|
||||
}
|
||||
|
||||
namespace solidity::langutil
|
||||
{
|
||||
|
||||
struct SourceLocation;
|
||||
struct SourceReference;
|
||||
|
||||
class SourceReferenceFormatterHuman: public SourceReferenceFormatter
|
||||
{
|
||||
public:
|
||||
SourceReferenceFormatterHuman(std::ostream& _stream, bool colored):
|
||||
SourceReferenceFormatter{_stream}, m_colored{colored}
|
||||
SourceReferenceFormatterHuman(std::ostream& _stream, bool _colored, bool _withErrorIds):
|
||||
SourceReferenceFormatter{_stream}, m_colored{_colored}, m_withErrorIds(_withErrorIds)
|
||||
{}
|
||||
|
||||
void printSourceLocation(SourceReference const& _ref) override;
|
||||
@ -54,12 +46,13 @@ public:
|
||||
static std::string formatExceptionInformation(
|
||||
util::Exception const& _exception,
|
||||
std::string const& _name,
|
||||
bool colored = false
|
||||
bool _colored = false,
|
||||
bool _withErrorIds = false
|
||||
)
|
||||
{
|
||||
std::ostringstream errorOutput;
|
||||
|
||||
SourceReferenceFormatterHuman formatter(errorOutput, colored);
|
||||
SourceReferenceFormatterHuman formatter(errorOutput, _colored, _withErrorIds);
|
||||
formatter.printExceptionInformation(_exception, _name);
|
||||
return errorOutput.str();
|
||||
}
|
||||
@ -75,6 +68,7 @@ private:
|
||||
|
||||
private:
|
||||
bool m_colored;
|
||||
bool m_withErrorIds;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -177,6 +177,7 @@ static string const g_strVersion = "version";
|
||||
static string const g_strIgnoreMissingFiles = "ignore-missing";
|
||||
static string const g_strColor = "color";
|
||||
static string const g_strNoColor = "no-color";
|
||||
static string const g_strErrorIds = "error-codes";
|
||||
static string const g_strOldReporter = "old-reporter";
|
||||
|
||||
static string const g_argAbi = g_strAbi;
|
||||
@ -222,6 +223,7 @@ static string const g_stdinFileName = g_stdinFileNameStr;
|
||||
static string const g_argIgnoreMissingFiles = g_strIgnoreMissingFiles;
|
||||
static string const g_argColor = g_strColor;
|
||||
static string const g_argNoColor = g_strNoColor;
|
||||
static string const g_argErrorIds = g_strErrorIds;
|
||||
static string const g_argOldReporter = g_strOldReporter;
|
||||
|
||||
/// Possible arguments to for --combined-json
|
||||
@ -876,6 +878,10 @@ General Information)").c_str(),
|
||||
g_argNoColor.c_str(),
|
||||
"Explicitly disable colored output, disabling terminal auto-detection."
|
||||
)
|
||||
(
|
||||
g_argErrorIds.c_str(),
|
||||
"Output error codes."
|
||||
)
|
||||
(
|
||||
g_argOldReporter.c_str(),
|
||||
"Enables old diagnostics reporter (legacy option, will be removed)."
|
||||
@ -989,6 +995,8 @@ General Information)").c_str(),
|
||||
|
||||
m_coloredOutput = !m_args.count(g_argNoColor) && (isatty(STDERR_FILENO) || m_args.count(g_argColor));
|
||||
|
||||
m_withErrorIds = m_args.count(g_argErrorIds);
|
||||
|
||||
if (m_args.count(g_argHelp) || (isatty(fileno(stdin)) && _argc == 1))
|
||||
{
|
||||
sout() << desc;
|
||||
@ -1294,7 +1302,7 @@ bool CommandLineInterface::processInput()
|
||||
if (m_args.count(g_argOldReporter))
|
||||
formatter = make_unique<SourceReferenceFormatter>(serr(false));
|
||||
else
|
||||
formatter = make_unique<SourceReferenceFormatterHuman>(serr(false), m_coloredOutput);
|
||||
formatter = make_unique<SourceReferenceFormatterHuman>(serr(false), m_coloredOutput, m_withErrorIds);
|
||||
|
||||
try
|
||||
{
|
||||
@ -1732,7 +1740,7 @@ bool CommandLineInterface::assemble(
|
||||
if (m_args.count(g_argOldReporter))
|
||||
formatter = make_unique<SourceReferenceFormatter>(serr(false));
|
||||
else
|
||||
formatter = make_unique<SourceReferenceFormatterHuman>(serr(false), m_coloredOutput);
|
||||
formatter = make_unique<SourceReferenceFormatterHuman>(serr(false), m_coloredOutput, m_withErrorIds);
|
||||
|
||||
for (auto const& error: stack.errors())
|
||||
{
|
||||
|
@ -131,6 +131,8 @@ private:
|
||||
CompilerStack::MetadataHash m_metadataHash = CompilerStack::MetadataHash::IPFS;
|
||||
/// Whether or not to colorize diagnostics output.
|
||||
bool m_coloredOutput = true;
|
||||
/// Whether or not to output error IDs.
|
||||
bool m_withErrorIds = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -121,6 +121,7 @@ function test_solc_behaviour()
|
||||
rm "$stdout_path.bak"
|
||||
else
|
||||
sed -i.bak -e '/^Warning: This is a pre-release compiler version, please do not use it in production./d' "$stderr_path"
|
||||
sed -i.bak -e '/^Warning (3805): This is a pre-release compiler version, please do not use it in production./d' "$stderr_path"
|
||||
sed -i.bak -e 's/\(^[ ]*auxdata: \)0x[0-9a-f]*$/\1AUXDATA REMOVED/' "$stdout_path"
|
||||
sed -i.bak -e 's/ Consider adding "pragma .*$//' "$stderr_path"
|
||||
# Remove trailing empty lines. Needs a line break to make OSX sed happy.
|
||||
|
1
test/cmdlineTests/error_codes/args
Normal file
1
test/cmdlineTests/error_codes/args
Normal file
@ -0,0 +1 @@
|
||||
--error-codes
|
26
test/cmdlineTests/error_codes/err
Normal file
26
test/cmdlineTests/error_codes/err
Normal file
@ -0,0 +1,26 @@
|
||||
Error (4937): No visibility specified. Did you intend to add "public"?
|
||||
--> error_codes/input.sol:4:5:
|
||||
|
|
||||
4 | function f() {
|
||||
| ^ (Relevant source part starts here and spans across multiple lines).
|
||||
|
||||
Warning (3420): Source file does not specify required compiler version!
|
||||
--> error_codes/input.sol
|
||||
|
||||
Error (4247): Expression has to be an lvalue.
|
||||
--> error_codes/input.sol:5:9:
|
||||
|
|
||||
5 | 2=0;
|
||||
| ^
|
||||
|
||||
Error (7407): Type int_const 0 is not implicitly convertible to expected type int_const 2.
|
||||
--> error_codes/input.sol:5:11:
|
||||
|
|
||||
5 | 2=0;
|
||||
| ^
|
||||
|
||||
Error (2614): Indexed expression has to be a type, mapping or array (is literal_string "")
|
||||
--> error_codes/input.sol:6:9:
|
||||
|
|
||||
6 | ""[2];
|
||||
| ^^
|
1
test/cmdlineTests/error_codes/exit
Normal file
1
test/cmdlineTests/error_codes/exit
Normal file
@ -0,0 +1 @@
|
||||
1
|
8
test/cmdlineTests/error_codes/input.sol
Normal file
8
test/cmdlineTests/error_codes/input.sol
Normal file
@ -0,0 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
|
||||
contract C {
|
||||
function f() {
|
||||
2=0;
|
||||
""[2];
|
||||
}
|
||||
}
|
@ -134,7 +134,7 @@ TestCase::TestResult ASTJSONTest::run(ostream& _stream, string const& _linePrefi
|
||||
c.analyze();
|
||||
else
|
||||
{
|
||||
SourceReferenceFormatterHuman formatter(_stream, _formatted);
|
||||
SourceReferenceFormatterHuman formatter(_stream, _formatted, false);
|
||||
for (auto const& error: c.errors())
|
||||
formatter.printErrorInformation(*error);
|
||||
return TestResult::FatalError;
|
||||
|
@ -118,7 +118,7 @@ TestCase::TestResult GasTest::run(ostream& _stream, string const& _linePrefix, b
|
||||
|
||||
if (!compiler().parseAndAnalyze() || !compiler().compile())
|
||||
{
|
||||
SourceReferenceFormatterHuman formatter(_stream, _formatted);
|
||||
SourceReferenceFormatterHuman formatter(_stream, _formatted, false);
|
||||
for (auto const& error: compiler().errors())
|
||||
formatter.printErrorInformation(*error);
|
||||
return TestResult::FatalError;
|
||||
|
@ -390,7 +390,7 @@ void SourceUpgrade::applyChange(
|
||||
|
||||
void SourceUpgrade::printErrors() const
|
||||
{
|
||||
auto formatter = make_unique<langutil::SourceReferenceFormatterHuman>(cout, true);
|
||||
auto formatter = make_unique<langutil::SourceReferenceFormatterHuman>(cout, true, false);
|
||||
|
||||
for (auto const& error: m_compiler->errors())
|
||||
if (error->type() != langutil::Error::Type::Warning)
|
||||
|
@ -36,7 +36,7 @@ void UpgradeChange::apply()
|
||||
void UpgradeChange::log(bool const _shorten) const
|
||||
{
|
||||
stringstream os;
|
||||
SourceReferenceFormatterHuman formatter{os, true};
|
||||
SourceReferenceFormatterHuman formatter{os, true, false};
|
||||
|
||||
string start = to_string(m_location.start);
|
||||
string end = to_string(m_location.end);
|
||||
|
Loading…
Reference in New Issue
Block a user