mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add new info severity
This commit is contained in:
parent
49cde9d47b
commit
e72fa7fc10
@ -389,6 +389,10 @@ code.
|
||||
Always use the latest version of the compiler to be notified about all recently
|
||||
introduced warnings.
|
||||
|
||||
Messages of type ``info`` issued by the compiler are not dangerous, and simply
|
||||
represent extra suggestions and optional information that the compiler thinks
|
||||
might be useful to the user.
|
||||
|
||||
Restrict the Amount of Ether
|
||||
============================
|
||||
|
||||
|
@ -437,7 +437,7 @@ Output Description
|
||||
.. code-block:: javascript
|
||||
|
||||
{
|
||||
// Optional: not present if no errors/warnings were encountered
|
||||
// Optional: not present if no errors/warnings/infos were encountered
|
||||
"errors": [
|
||||
{
|
||||
// Optional: Location within the source file.
|
||||
@ -460,7 +460,7 @@ Output Description
|
||||
"type": "TypeError",
|
||||
// Mandatory: Component where the error originated, such as "general", "ewasm", etc.
|
||||
"component": "general",
|
||||
// Mandatory ("error" or "warning")
|
||||
// Mandatory ("error", "warning" or "info", but please note that this may be extended in the future)
|
||||
"severity": "error",
|
||||
// Optional: unique code for the cause of the error
|
||||
"errorCode": "3141",
|
||||
@ -604,6 +604,7 @@ Error Types
|
||||
11. ``CompilerError``: Invalid use of the compiler stack - this should be reported as an issue.
|
||||
12. ``FatalError``: Fatal error not processed correctly - this should be reported as an issue.
|
||||
13. ``Warning``: A warning, which didn't stop the compilation, but should be addressed if possible.
|
||||
14. ``Info``: Information that the compiler thinks the user might find useful, but is not dangerous and does not necessarily need to be addressed.
|
||||
|
||||
|
||||
.. _compiler-tools:
|
||||
|
@ -94,6 +94,16 @@ bool ErrorReporter::checkForExcessiveErrors(Error::Type _type)
|
||||
if (m_warningCount >= c_maxWarningsAllowed)
|
||||
return true;
|
||||
}
|
||||
else if (_type == Error::Type::Info)
|
||||
{
|
||||
m_infoCount++;
|
||||
|
||||
if (m_infoCount == c_maxInfosAllowed)
|
||||
m_errorList.push_back(make_shared<Error>(2833_error, Error::Type::Info, "There are more than 256 infos. Ignoring the rest."));
|
||||
|
||||
if (m_infoCount >= c_maxInfosAllowed)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_errorCount++;
|
||||
@ -242,3 +252,12 @@ void ErrorReporter::docstringParsingError(ErrorId _error, SourceLocation const&
|
||||
_description
|
||||
);
|
||||
}
|
||||
|
||||
void ErrorReporter::info(
|
||||
ErrorId _error,
|
||||
SourceLocation const& _location,
|
||||
string const& _description
|
||||
)
|
||||
{
|
||||
error(_error, Error::Type::Info, _location, _description);
|
||||
}
|
||||
|
@ -63,6 +63,8 @@ public:
|
||||
SecondarySourceLocation const& _secondaryLocation
|
||||
);
|
||||
|
||||
void info(ErrorId _error, SourceLocation const& _location, std::string const& _description);
|
||||
|
||||
void error(
|
||||
ErrorId _error,
|
||||
Error::Type _type,
|
||||
@ -118,13 +120,13 @@ public:
|
||||
|
||||
void clear();
|
||||
|
||||
/// @returns true iff there is any error (ignores warnings).
|
||||
/// @returns true iff there is any error (ignores warnings and infos).
|
||||
bool hasErrors() const
|
||||
{
|
||||
return m_errorCount > 0;
|
||||
}
|
||||
|
||||
/// @returns the number of errors (ignores warnings).
|
||||
/// @returns the number of errors (ignores warnings and infos).
|
||||
unsigned errorCount() const
|
||||
{
|
||||
return m_errorCount;
|
||||
@ -183,9 +185,11 @@ private:
|
||||
|
||||
unsigned m_errorCount = 0;
|
||||
unsigned m_warningCount = 0;
|
||||
unsigned m_infoCount = 0;
|
||||
|
||||
unsigned const c_maxWarningsAllowed = 256;
|
||||
unsigned const c_maxErrorsAllowed = 256;
|
||||
unsigned const c_maxInfosAllowed = 256;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -47,6 +47,9 @@ Error::Error(
|
||||
case Type::DocstringParsingError:
|
||||
m_typeName = "DocstringParsingError";
|
||||
break;
|
||||
case Type::Info:
|
||||
m_typeName = "Info";
|
||||
break;
|
||||
case Type::ParserError:
|
||||
m_typeName = "ParserError";
|
||||
break;
|
||||
|
@ -120,7 +120,15 @@ public:
|
||||
ParserError,
|
||||
TypeError,
|
||||
SyntaxError,
|
||||
Warning
|
||||
Warning,
|
||||
Info
|
||||
};
|
||||
|
||||
enum class Severity
|
||||
{
|
||||
Error,
|
||||
Warning,
|
||||
Info
|
||||
};
|
||||
|
||||
Error(
|
||||
@ -139,21 +147,63 @@ public:
|
||||
static Error const* containsErrorOfType(ErrorList const& _list, Error::Type _type)
|
||||
{
|
||||
for (auto e: _list)
|
||||
{
|
||||
if (e->type() == _type)
|
||||
return e.get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static bool containsOnlyWarnings(ErrorList const& _list)
|
||||
|
||||
static Severity errorSeverity(Type _type)
|
||||
{
|
||||
if (_type == Type::Info)
|
||||
return Severity::Info;
|
||||
if (_type == Type::Warning)
|
||||
return Severity::Warning;
|
||||
return Severity::Error;
|
||||
}
|
||||
|
||||
static bool isError(Severity _severity)
|
||||
{
|
||||
return _severity == Severity::Error;
|
||||
}
|
||||
|
||||
static bool isError(Type _type)
|
||||
{
|
||||
return isError(errorSeverity(_type));
|
||||
}
|
||||
|
||||
static bool containsErrors(ErrorList const& _list)
|
||||
{
|
||||
for (auto e: _list)
|
||||
{
|
||||
if (e->type() != Type::Warning)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (isError(e->type()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static std::string formatErrorSeverity(Severity _severity)
|
||||
{
|
||||
if (_severity == Severity::Info)
|
||||
return "Info";
|
||||
if (_severity == Severity::Warning)
|
||||
return "Warning";
|
||||
solAssert(isError(_severity), "");
|
||||
return "Error";
|
||||
}
|
||||
|
||||
static std::string formatErrorSeverityLowercase(Severity _severity)
|
||||
{
|
||||
switch (_severity)
|
||||
{
|
||||
case Severity::Info:
|
||||
return "info";
|
||||
case Severity::Warning:
|
||||
return "warning";
|
||||
case Severity::Error:
|
||||
solAssert(isError(_severity), "");
|
||||
return "error";
|
||||
}
|
||||
solAssert(false, "");
|
||||
}
|
||||
|
||||
private:
|
||||
ErrorId m_errorId;
|
||||
Type m_type;
|
||||
|
@ -104,7 +104,7 @@ protected:
|
||||
void fatalParserError(ErrorId _error, SourceLocation const& _location, std::string const& _description);
|
||||
|
||||
std::shared_ptr<Scanner> m_scanner;
|
||||
/// The reference to the list of errors and warning to add errors/warnings during parsing
|
||||
/// The reference to the list of errors, warnings and infos to add errors/warnings/infos during parsing
|
||||
ErrorReporter& m_errorReporter;
|
||||
/// Current recursion depth during parsing.
|
||||
size_t m_recursionDepth = 0;
|
||||
|
@ -30,7 +30,7 @@ using namespace solidity::langutil;
|
||||
SourceReferenceExtractor::Message SourceReferenceExtractor::extract(
|
||||
CharStreamProvider const& _charStreamProvider,
|
||||
util::Exception const& _exception,
|
||||
string _category
|
||||
string _severity
|
||||
)
|
||||
{
|
||||
SourceLocation const* location = boost::get_error_info<errinfo_sourceLocation>(_exception);
|
||||
@ -44,7 +44,7 @@ SourceReferenceExtractor::Message SourceReferenceExtractor::extract(
|
||||
for (auto const& info: secondaryLocation->infos)
|
||||
secondary.emplace_back(extract(_charStreamProvider, &info.second, info.first));
|
||||
|
||||
return Message{std::move(primary), _category, std::move(secondary), nullopt};
|
||||
return Message{std::move(primary), _severity, std::move(secondary), nullopt};
|
||||
}
|
||||
|
||||
SourceReferenceExtractor::Message SourceReferenceExtractor::extract(
|
||||
@ -52,8 +52,8 @@ SourceReferenceExtractor::Message SourceReferenceExtractor::extract(
|
||||
Error const& _error
|
||||
)
|
||||
{
|
||||
string category = (_error.type() == Error::Type::Warning) ? "Warning" : "Error";
|
||||
Message message = extract(_charStreamProvider, _error, category);
|
||||
string severity = Error::formatErrorSeverity(Error::errorSeverity(_error.type()));
|
||||
Message message = extract(_charStreamProvider, _error, severity);
|
||||
message.errorId = _error.errorId();
|
||||
return message;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ struct LineColumn
|
||||
|
||||
struct SourceReference
|
||||
{
|
||||
std::string message; ///< A message that relates to this source reference (such as a warning or an error message).
|
||||
std::string message; ///< A message that relates to this source reference (such as a warning, info or an error message).
|
||||
std::string sourceName; ///< Underlying source name (for example the filename).
|
||||
LineColumn position; ///< Actual (error) position this source reference is surrounding.
|
||||
bool multiline = {false}; ///< Indicates whether the actual SourceReference is truncated to one line.
|
||||
@ -64,12 +64,12 @@ namespace SourceReferenceExtractor
|
||||
struct Message
|
||||
{
|
||||
SourceReference primary;
|
||||
std::string category; // "Error", "Warning", ...
|
||||
std::string severity; // "Error", "Warning", "Info", ...
|
||||
std::vector<SourceReference> secondary;
|
||||
std::optional<ErrorId> errorId;
|
||||
};
|
||||
|
||||
Message extract(CharStreamProvider const& _charStreamProvider, util::Exception const& _exception, std::string _category);
|
||||
Message extract(CharStreamProvider const& _charStreamProvider, util::Exception const& _exception, std::string _severity);
|
||||
Message extract(CharStreamProvider const& _charStreamProvider, Error const& _error);
|
||||
SourceReference extract(CharStreamProvider const& _charStreamProvider, SourceLocation const* _location, std::string message = "");
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ void SourceReferenceFormatter::printSourceLocation(SourceReference const& _ref)
|
||||
void SourceReferenceFormatter::printExceptionInformation(SourceReferenceExtractor::Message const& _msg)
|
||||
{
|
||||
// exception header line
|
||||
errorColored() << _msg.category;
|
||||
errorColored() << _msg.severity;
|
||||
if (m_withErrorIds && _msg.errorId.has_value())
|
||||
errorColored() << " (" << _msg.errorId.value().error << ")";
|
||||
messageColored() << ": " << _msg.primary.message << '\n';
|
||||
@ -181,9 +181,9 @@ void SourceReferenceFormatter::printExceptionInformation(SourceReferenceExtracto
|
||||
m_stream << '\n';
|
||||
}
|
||||
|
||||
void SourceReferenceFormatter::printExceptionInformation(util::Exception const& _exception, std::string const& _category)
|
||||
void SourceReferenceFormatter::printExceptionInformation(util::Exception const& _exception, std::string const& _severity)
|
||||
{
|
||||
printExceptionInformation(SourceReferenceExtractor::extract(m_charStreamProvider, _exception, _category));
|
||||
printExceptionInformation(SourceReferenceExtractor::extract(m_charStreamProvider, _exception, _severity));
|
||||
}
|
||||
|
||||
void SourceReferenceFormatter::printErrorInformation(ErrorList const& _errors)
|
||||
|
@ -52,7 +52,7 @@ public:
|
||||
/// Prints source location if it is given.
|
||||
void printSourceLocation(SourceReference const& _ref);
|
||||
void printExceptionInformation(SourceReferenceExtractor::Message const& _msg);
|
||||
void printExceptionInformation(util::Exception const& _exception, std::string const& _category);
|
||||
void printExceptionInformation(util::Exception const& _exception, std::string const& _severity);
|
||||
void printErrorInformation(langutil::ErrorList const& _errors);
|
||||
void printErrorInformation(Error const& _error);
|
||||
|
||||
@ -77,7 +77,7 @@ public:
|
||||
{
|
||||
return formatExceptionInformation(
|
||||
_error,
|
||||
(_error.type() == Error::Type::Warning) ? "Warning" : "Error",
|
||||
Error::formatErrorSeverity(Error::errorSeverity(_error.type())),
|
||||
_charStreamProvider
|
||||
);
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ bool ContractLevelChecker::check(SourceUnit const& _sourceUnit)
|
||||
findDuplicateDefinitions(
|
||||
filterDeclarations<EventDefinition>(*_sourceUnit.annotation().exportedSymbols)
|
||||
);
|
||||
if (!Error::containsOnlyWarnings(m_errorReporter.errors()))
|
||||
if (Error::containsErrors(m_errorReporter.errors()))
|
||||
noErrors = false;
|
||||
for (ASTPointer<ASTNode> const& node: _sourceUnit.nodes())
|
||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||
@ -97,7 +97,7 @@ bool ContractLevelChecker::check(ContractDefinition const& _contract)
|
||||
checkPayableFallbackWithoutReceive(_contract);
|
||||
checkStorageSize(_contract);
|
||||
|
||||
return Error::containsOnlyWarnings(m_errorReporter.errors());
|
||||
return !Error::containsErrors(m_errorReporter.errors());
|
||||
}
|
||||
|
||||
void ContractLevelChecker::checkDuplicateFunctions(ContractDefinition const& _contract)
|
||||
|
@ -36,7 +36,7 @@ bool ControlFlowAnalyzer::run()
|
||||
for (auto& [pair, flow]: m_cfg.allFunctionFlows())
|
||||
analyze(*pair.function, pair.contract, *flow);
|
||||
|
||||
return Error::containsOnlyWarnings(m_errorReporter.errors());
|
||||
return !Error::containsErrors(m_errorReporter.errors());
|
||||
}
|
||||
|
||||
void ControlFlowAnalyzer::analyze(FunctionDefinition const& _function, ContractDefinition const* _contract, FunctionFlow const& _flow)
|
||||
|
@ -27,7 +27,7 @@ using namespace solidity::frontend;
|
||||
bool CFG::constructFlow(ASTNode const& _astRoot)
|
||||
{
|
||||
_astRoot.accept(*this);
|
||||
return Error::containsOnlyWarnings(m_errorReporter.errors());
|
||||
return !Error::containsErrors(m_errorReporter.errors());
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,14 +36,14 @@ using namespace solidity::frontend;
|
||||
bool PostTypeChecker::check(ASTNode const& _astRoot)
|
||||
{
|
||||
_astRoot.accept(*this);
|
||||
return Error::containsOnlyWarnings(m_errorReporter.errors());
|
||||
return !Error::containsErrors(m_errorReporter.errors());
|
||||
}
|
||||
|
||||
bool PostTypeChecker::finalize()
|
||||
{
|
||||
for (auto& checker: m_checkers)
|
||||
checker->finalize();
|
||||
return Error::containsOnlyWarnings(m_errorReporter.errors());
|
||||
return !Error::containsErrors(m_errorReporter.errors());
|
||||
}
|
||||
|
||||
bool PostTypeChecker::visit(ContractDefinition const& _contractDefinition)
|
||||
|
@ -68,5 +68,5 @@ bool PostTypeContractLevelChecker::check(ContractDefinition const& _contract)
|
||||
errorHashes[hash][signature] = error->location();
|
||||
}
|
||||
|
||||
return Error::containsOnlyWarnings(m_errorReporter.errors());
|
||||
return !Error::containsErrors(m_errorReporter.errors());
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ StaticAnalyzer::~StaticAnalyzer()
|
||||
bool StaticAnalyzer::analyze(SourceUnit const& _sourceUnit)
|
||||
{
|
||||
_sourceUnit.accept(*this);
|
||||
return Error::containsOnlyWarnings(m_errorReporter.errors());
|
||||
return !Error::containsErrors(m_errorReporter.errors());
|
||||
}
|
||||
|
||||
bool StaticAnalyzer::visit(ContractDefinition const& _contract)
|
||||
|
@ -41,7 +41,7 @@ using namespace solidity::util;
|
||||
bool SyntaxChecker::checkSyntax(ASTNode const& _astRoot)
|
||||
{
|
||||
_astRoot.accept(*this);
|
||||
return Error::containsOnlyWarnings(m_errorReporter.errors());
|
||||
return !Error::containsErrors(m_errorReporter.errors());
|
||||
}
|
||||
|
||||
bool SyntaxChecker::visit(SourceUnit const& _sourceUnit)
|
||||
|
@ -73,7 +73,7 @@ bool TypeChecker::checkTypeRequirements(SourceUnit const& _source)
|
||||
m_currentSourceUnit = &_source;
|
||||
_source.accept(*this);
|
||||
m_currentSourceUnit = nullptr;
|
||||
return Error::containsOnlyWarnings(m_errorReporter.errors());
|
||||
return !Error::containsErrors(m_errorReporter.errors());
|
||||
}
|
||||
|
||||
Type const* TypeChecker::type(Expression const& _expression) const
|
||||
|
@ -338,7 +338,7 @@ bool CompilerStack::parse()
|
||||
Source& source = m_sources[path];
|
||||
source.ast = parser.parse(*source.charStream);
|
||||
if (!source.ast)
|
||||
solAssert(!Error::containsOnlyWarnings(m_errorReporter.errors()), "Parser returned null but did not report error.");
|
||||
solAssert(Error::containsErrors(m_errorReporter.errors()), "Parser returned null but did not report error.");
|
||||
else
|
||||
{
|
||||
source.ast->annotation().path = path;
|
||||
@ -357,7 +357,7 @@ bool CompilerStack::parse()
|
||||
m_stackState = Parsed;
|
||||
else
|
||||
m_stackState = ParsedAndImported;
|
||||
if (!Error::containsOnlyWarnings(m_errorReporter.errors()))
|
||||
if (Error::containsErrors(m_errorReporter.errors()))
|
||||
m_hasError = true;
|
||||
|
||||
storeContractDefinitions();
|
||||
|
@ -50,7 +50,7 @@ namespace
|
||||
{
|
||||
|
||||
Json::Value formatError(
|
||||
bool _warning,
|
||||
Error::Severity _severity,
|
||||
string const& _type,
|
||||
string const& _component,
|
||||
string const& _message,
|
||||
@ -62,7 +62,7 @@ Json::Value formatError(
|
||||
Json::Value error = Json::objectValue;
|
||||
error["type"] = _type;
|
||||
error["component"] = _component;
|
||||
error["severity"] = _warning ? "warning" : "error";
|
||||
error["severity"] = Error::formatErrorSeverityLowercase(_severity);
|
||||
error["message"] = _message;
|
||||
error["formattedMessage"] = (_formattedMessage.length() > 0) ? _formattedMessage : _message;
|
||||
if (_sourceLocation.isObject())
|
||||
@ -76,7 +76,7 @@ Json::Value formatFatalError(string const& _type, string const& _message)
|
||||
{
|
||||
Json::Value output = Json::objectValue;
|
||||
output["errors"] = Json::arrayValue;
|
||||
output["errors"].append(formatError(false, _type, "general", _message));
|
||||
output["errors"].append(formatError(Error::Severity::Error, _type, "general", _message));
|
||||
return output;
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ Json::Value formatSecondarySourceLocation(SecondarySourceLocation const* _second
|
||||
Json::Value formatErrorWithException(
|
||||
CharStreamProvider const& _charStreamProvider,
|
||||
util::Exception const& _exception,
|
||||
bool const& _warning,
|
||||
Error::Severity _severity,
|
||||
string const& _type,
|
||||
string const& _component,
|
||||
string const& _message,
|
||||
@ -132,7 +132,7 @@ Json::Value formatErrorWithException(
|
||||
message = _message;
|
||||
|
||||
Json::Value error = formatError(
|
||||
_warning,
|
||||
_severity,
|
||||
_type,
|
||||
_component,
|
||||
message,
|
||||
@ -660,7 +660,7 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
|
||||
string content = sources[sourceName]["content"].asString();
|
||||
if (!hash.empty() && !hashMatchesContent(hash, content))
|
||||
ret.errors.append(formatError(
|
||||
false,
|
||||
Error::Severity::Error,
|
||||
"IOError",
|
||||
"general",
|
||||
"Mismatch between content and supplied hash for \"" + sourceName + "\""
|
||||
@ -685,7 +685,7 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
|
||||
{
|
||||
if (!hash.empty() && !hashMatchesContent(hash, result.responseOrErrorMessage))
|
||||
ret.errors.append(formatError(
|
||||
false,
|
||||
Error::Severity::Error,
|
||||
"IOError",
|
||||
"general",
|
||||
"Mismatch between content and supplied hash for \"" + sourceName + "\" at \"" + url.asString() + "\""
|
||||
@ -705,7 +705,7 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
|
||||
{
|
||||
/// If the import succeeded, let mark all the others as warnings, otherwise all of them are errors.
|
||||
ret.errors.append(formatError(
|
||||
found ? true : false,
|
||||
found ? Error::Severity::Warning : Error::Severity::Error,
|
||||
"IOError",
|
||||
"general",
|
||||
failure
|
||||
@ -1058,7 +1058,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
errors.append(formatErrorWithException(
|
||||
compilerStack,
|
||||
*error,
|
||||
err.type() == Error::Type::Warning,
|
||||
Error::errorSeverity(err.type()),
|
||||
err.typeName(),
|
||||
"general",
|
||||
"",
|
||||
@ -1072,7 +1072,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
errors.append(formatErrorWithException(
|
||||
compilerStack,
|
||||
_error,
|
||||
false,
|
||||
Error::Severity::Error,
|
||||
_error.typeName(),
|
||||
"general",
|
||||
"Uncaught error: "
|
||||
@ -1082,7 +1082,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
catch (FatalError const& _exception)
|
||||
{
|
||||
errors.append(formatError(
|
||||
false,
|
||||
Error::Severity::Error,
|
||||
"FatalError",
|
||||
"general",
|
||||
"Uncaught fatal error: " + boost::diagnostic_information(_exception)
|
||||
@ -1093,7 +1093,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
errors.append(formatErrorWithException(
|
||||
compilerStack,
|
||||
_exception,
|
||||
false,
|
||||
Error::Severity::Error,
|
||||
"CompilerError",
|
||||
"general",
|
||||
"Compiler error (" + _exception.lineInfo() + ")"
|
||||
@ -1104,7 +1104,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
errors.append(formatErrorWithException(
|
||||
compilerStack,
|
||||
_exception,
|
||||
false,
|
||||
Error::Severity::Error,
|
||||
"InternalCompilerError",
|
||||
"general",
|
||||
"Internal compiler error (" + _exception.lineInfo() + ")"
|
||||
@ -1115,7 +1115,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
errors.append(formatErrorWithException(
|
||||
compilerStack,
|
||||
_exception,
|
||||
false,
|
||||
Error::Severity::Error,
|
||||
"UnimplementedFeatureError",
|
||||
"general",
|
||||
"Unimplemented feature (" + _exception.lineInfo() + ")"
|
||||
@ -1126,7 +1126,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
errors.append(formatErrorWithException(
|
||||
compilerStack,
|
||||
_exception,
|
||||
false,
|
||||
Error::Severity::Error,
|
||||
"YulException",
|
||||
"general",
|
||||
"Yul exception"
|
||||
@ -1137,7 +1137,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
errors.append(formatErrorWithException(
|
||||
compilerStack,
|
||||
_exception,
|
||||
false,
|
||||
Error::Severity::Error,
|
||||
"SMTLogicException",
|
||||
"general",
|
||||
"SMT logic exception"
|
||||
@ -1146,7 +1146,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
catch (util::Exception const& _exception)
|
||||
{
|
||||
errors.append(formatError(
|
||||
false,
|
||||
Error::Severity::Error,
|
||||
"Exception",
|
||||
"general",
|
||||
"Exception during compilation: " + boost::diagnostic_information(_exception)
|
||||
@ -1155,7 +1155,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
catch (std::exception const& _e)
|
||||
{
|
||||
errors.append(formatError(
|
||||
false,
|
||||
Error::Severity::Error,
|
||||
"Exception",
|
||||
"general",
|
||||
"Unknown exception during compilation" + (_e.what() ? ": " + string(_e.what()) : ".")
|
||||
@ -1164,7 +1164,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
|
||||
catch (...)
|
||||
{
|
||||
errors.append(formatError(
|
||||
false,
|
||||
Error::Severity::Error,
|
||||
"Exception",
|
||||
"general",
|
||||
"Unknown exception during compilation."
|
||||
@ -1345,7 +1345,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
|
||||
errors.append(formatErrorWithException(
|
||||
stack,
|
||||
*error,
|
||||
err->type() == Error::Type::Warning,
|
||||
Error::errorSeverity(err->type()),
|
||||
err->typeName(),
|
||||
"general",
|
||||
""
|
||||
@ -1357,7 +1357,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
|
||||
|
||||
// TODO: move this warning to AssemblyStack
|
||||
output["errors"] = Json::arrayValue;
|
||||
output["errors"].append(formatError(true, "Warning", "general", "Yul is still experimental. Please use the output with care."));
|
||||
output["errors"].append(formatError(Error::Severity::Warning, "Warning", "general", "Yul is still experimental. Please use the output with care."));
|
||||
|
||||
string contractName = stack.parserResult()->name.str();
|
||||
|
||||
|
@ -226,7 +226,7 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False):
|
||||
|
||||
old_source_only_ids = {
|
||||
"1584", "1823",
|
||||
"1988", "2066", "3356",
|
||||
"1988", "2066", "2833", "3356",
|
||||
"3893", "3996", "4010", "4802",
|
||||
"5272", "5622", "7128", "7400",
|
||||
"7589", "7593", "7649", "7710",
|
||||
|
@ -976,7 +976,7 @@ bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul:
|
||||
m_hasOutput = true;
|
||||
formatter.printErrorInformation(*error);
|
||||
}
|
||||
if (!Error::containsOnlyWarnings(stack.errors()))
|
||||
if (Error::containsErrors(stack.errors()))
|
||||
successful = false;
|
||||
}
|
||||
|
||||
|
@ -75,24 +75,24 @@ AnalysisFramework::parseAnalyseAndReturnError(
|
||||
return make_pair(&compiler().ast(""), std::move(errors));
|
||||
}
|
||||
|
||||
ErrorList AnalysisFramework::filterErrors(ErrorList const& _errorList, bool _includeWarnings) const
|
||||
ErrorList AnalysisFramework::filterErrors(ErrorList const& _errorList, bool _includeWarningsAndInfos) const
|
||||
{
|
||||
ErrorList errors;
|
||||
for (auto const& currentError: _errorList)
|
||||
{
|
||||
solAssert(currentError->comment(), "");
|
||||
if (currentError->type() == Error::Type::Warning)
|
||||
if (!Error::isError(currentError->type()))
|
||||
{
|
||||
if (!_includeWarnings)
|
||||
if (!_includeWarningsAndInfos)
|
||||
continue;
|
||||
bool ignoreWarning = false;
|
||||
bool ignoreWarningsAndInfos = false;
|
||||
for (auto const& filter: m_warningsToFilter)
|
||||
if (currentError->comment()->find(filter) == 0)
|
||||
{
|
||||
ignoreWarning = true;
|
||||
ignoreWarningsAndInfos = true;
|
||||
break;
|
||||
}
|
||||
if (ignoreWarning)
|
||||
if (ignoreWarningsAndInfos)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -66,8 +66,8 @@ protected:
|
||||
std::string const& _signature
|
||||
);
|
||||
|
||||
// filter out the warnings in m_warningsToFilter or all warnings if _includeWarnings is false
|
||||
langutil::ErrorList filterErrors(langutil::ErrorList const& _errorList, bool _includeWarnings) const;
|
||||
// filter out the warnings in m_warningsToFilter or all warnings and infos if _includeWarningsAndInfos is false
|
||||
langutil::ErrorList filterErrors(langutil::ErrorList const& _errorList, bool _includeWarningsAndInfos) const;
|
||||
|
||||
std::vector<std::string> m_warningsToFilter = {"This is a pre-release compiler version"};
|
||||
std::vector<std::string> m_messagesToCut = {"Source file requires different compiler version (current compiler is"};
|
||||
|
@ -67,20 +67,20 @@ evmasm::AssemblyItems compileContract(std::shared_ptr<CharStream> _sourceCode)
|
||||
GlobalContext globalContext;
|
||||
NameAndTypeResolver resolver(globalContext, solidity::test::CommonOptions::get().evmVersion(), errorReporter);
|
||||
DeclarationTypeChecker declarationTypeChecker(errorReporter, solidity::test::CommonOptions::get().evmVersion());
|
||||
solAssert(Error::containsOnlyWarnings(errorReporter.errors()), "");
|
||||
solAssert(!Error::containsErrors(errorReporter.errors()), "");
|
||||
resolver.registerDeclarations(*sourceUnit);
|
||||
BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*sourceUnit));
|
||||
if (!Error::containsOnlyWarnings(errorReporter.errors()))
|
||||
if (Error::containsErrors(errorReporter.errors()))
|
||||
return AssemblyItems();
|
||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||
{
|
||||
BOOST_REQUIRE_NO_THROW(declarationTypeChecker.check(*node));
|
||||
if (!Error::containsOnlyWarnings(errorReporter.errors()))
|
||||
if (Error::containsErrors(errorReporter.errors()))
|
||||
return AssemblyItems();
|
||||
}
|
||||
TypeChecker checker(solidity::test::CommonOptions::get().evmVersion(), errorReporter);
|
||||
BOOST_REQUIRE_NO_THROW(checker.checkTypeRequirements(*sourceUnit));
|
||||
if (!Error::containsOnlyWarnings(errorReporter.errors()))
|
||||
if (Error::containsErrors(errorReporter.errors()))
|
||||
return AssemblyItems();
|
||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||
|
@ -128,7 +128,7 @@ void parsePrintCompare(string const& _source, bool _canWarn = false)
|
||||
AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), AssemblyStack::Language::Assembly, OptimiserSettings::none());
|
||||
BOOST_REQUIRE(stack.parseAndAnalyze("", _source));
|
||||
if (_canWarn)
|
||||
BOOST_REQUIRE(Error::containsOnlyWarnings(stack.errors()));
|
||||
BOOST_REQUIRE(!Error::containsErrors(stack.errors()));
|
||||
else
|
||||
BOOST_REQUIRE(stack.errors().empty());
|
||||
string expectation = "object \"object\" {\n code " + boost::replace_all_copy(_source, "\n", "\n ") + "\n}\n";
|
||||
|
@ -74,7 +74,7 @@ bool successParse(std::string const& _source)
|
||||
if (Error::containsErrorOfType(errors, Error::Type::ParserError))
|
||||
return false;
|
||||
|
||||
BOOST_CHECK(Error::containsOnlyWarnings(errors));
|
||||
BOOST_CHECK(!Error::containsErrors(errors));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,19 @@ namespace solidity::frontend::test
|
||||
namespace
|
||||
{
|
||||
|
||||
langutil::Error::Severity str2Severity(string const& _cat)
|
||||
{
|
||||
map<string, langutil::Error::Severity> cats{
|
||||
{"info", langutil::Error::Severity::Info},
|
||||
{"Info", langutil::Error::Severity::Info},
|
||||
{"warning", langutil::Error::Severity::Warning},
|
||||
{"Warning", langutil::Error::Severity::Warning},
|
||||
{"error", langutil::Error::Severity::Error},
|
||||
{"Error", langutil::Error::Severity::Error}
|
||||
};
|
||||
return cats.at(_cat);
|
||||
}
|
||||
|
||||
/// Helper to match a specific error type and message
|
||||
bool containsError(Json::Value const& _compilerResult, string const& _type, string const& _message)
|
||||
{
|
||||
@ -68,7 +81,7 @@ bool containsAtMostWarnings(Json::Value const& _compilerResult)
|
||||
{
|
||||
BOOST_REQUIRE(error.isObject());
|
||||
BOOST_REQUIRE(error["severity"].isString());
|
||||
if (error["severity"].asString() != "warning")
|
||||
if (langutil::Error::isError(str2Severity(error["severity"].asString())))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ void SyntaxTest::parseAndAnalyze()
|
||||
return error->type() == Error::Type::CodeGenerationError;
|
||||
});
|
||||
auto errorCount = count_if(errors.cbegin(), errors.cend(), [](auto const& error) {
|
||||
return error->type() != Error::Type::Warning;
|
||||
return Error::isError(error->type());
|
||||
});
|
||||
// failing compilation after successful analysis is a rare case,
|
||||
// it assumes that errors contain exactly one error, and the error is of type Error::Type::CodeGenerationError
|
||||
|
@ -200,7 +200,7 @@ TestCase::TestResult ControlFlowGraphTest::run(ostream& _stream, string const& _
|
||||
{
|
||||
ErrorList errors;
|
||||
auto [object, analysisInfo] = parse(m_source, *m_dialect, errors);
|
||||
if (!object || !analysisInfo || !Error::containsOnlyWarnings(errors))
|
||||
if (!object || !analysisInfo || Error::containsErrors(errors))
|
||||
{
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << endl;
|
||||
return TestResult::FatalError;
|
||||
|
@ -72,7 +72,7 @@ pair<bool, ErrorList> parse(string const& _source)
|
||||
return {false, {}};
|
||||
}
|
||||
|
||||
optional<Error> parseAndReturnFirstError(string const& _source, bool _allowWarnings = true)
|
||||
optional<Error> parseAndReturnFirstError(string const& _source, bool _allowWarningsAndInfos = true)
|
||||
{
|
||||
bool success;
|
||||
ErrorList errors;
|
||||
@ -85,11 +85,11 @@ optional<Error> parseAndReturnFirstError(string const& _source, bool _allowWarni
|
||||
else
|
||||
{
|
||||
// If success is true, there might still be an error in the assembly stage.
|
||||
if (_allowWarnings && Error::containsOnlyWarnings(errors))
|
||||
if (_allowWarningsAndInfos && !Error::containsErrors(errors))
|
||||
return {};
|
||||
else if (!errors.empty())
|
||||
{
|
||||
if (!_allowWarnings)
|
||||
if (!_allowWarningsAndInfos)
|
||||
BOOST_CHECK_EQUAL(errors.size(), 1);
|
||||
return *errors.front();
|
||||
}
|
||||
@ -97,15 +97,15 @@ optional<Error> parseAndReturnFirstError(string const& _source, bool _allowWarni
|
||||
return {};
|
||||
}
|
||||
|
||||
bool successParse(string const& _source, bool _allowWarnings = true)
|
||||
bool successParse(string const& _source, bool _allowWarningsAndInfos = true)
|
||||
{
|
||||
return !parseAndReturnFirstError(_source, _allowWarnings);
|
||||
return !parseAndReturnFirstError(_source, _allowWarningsAndInfos);
|
||||
}
|
||||
|
||||
Error expectError(string const& _source, bool _allowWarnings = false)
|
||||
Error expectError(string const& _source, bool _allowWarningsAndInfos = false)
|
||||
{
|
||||
|
||||
auto error = parseAndReturnFirstError(_source, _allowWarnings);
|
||||
auto error = parseAndReturnFirstError(_source, _allowWarningsAndInfos);
|
||||
BOOST_REQUIRE(error);
|
||||
return *error;
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ shared_ptr<Block> parse(string const& _source, Dialect const& _dialect, ErrorRep
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<Error> parseAndReturnFirstError(string const& _source, Dialect const& _dialect, bool _allowWarnings = true)
|
||||
std::optional<Error> parseAndReturnFirstError(string const& _source, Dialect const& _dialect, bool _allowWarningsAndInfos = true)
|
||||
{
|
||||
ErrorList errors;
|
||||
ErrorReporter errorReporter(errors);
|
||||
@ -98,11 +98,11 @@ std::optional<Error> parseAndReturnFirstError(string const& _source, Dialect con
|
||||
else
|
||||
{
|
||||
// If success is true, there might still be an error in the assembly stage.
|
||||
if (_allowWarnings && Error::containsOnlyWarnings(errors))
|
||||
if (_allowWarningsAndInfos && !Error::containsErrors(errors))
|
||||
return {};
|
||||
else if (!errors.empty())
|
||||
{
|
||||
if (!_allowWarnings)
|
||||
if (!_allowWarningsAndInfos)
|
||||
BOOST_CHECK_EQUAL(errors.size(), 1);
|
||||
return *errors.front();
|
||||
}
|
||||
@ -110,15 +110,15 @@ std::optional<Error> parseAndReturnFirstError(string const& _source, Dialect con
|
||||
return {};
|
||||
}
|
||||
|
||||
bool successParse(std::string const& _source, Dialect const& _dialect = Dialect::yulDeprecated(), bool _allowWarnings = true)
|
||||
bool successParse(std::string const& _source, Dialect const& _dialect = Dialect::yulDeprecated(), bool _allowWarningsAndInfos = true)
|
||||
{
|
||||
return !parseAndReturnFirstError(_source, _dialect, _allowWarnings);
|
||||
return !parseAndReturnFirstError(_source, _dialect, _allowWarningsAndInfos);
|
||||
}
|
||||
|
||||
Error expectError(std::string const& _source, Dialect const& _dialect = Dialect::yulDeprecated(), bool _allowWarnings = false)
|
||||
Error expectError(std::string const& _source, Dialect const& _dialect = Dialect::yulDeprecated(), bool _allowWarningsAndInfos = false)
|
||||
{
|
||||
|
||||
auto error = parseAndReturnFirstError(_source, _dialect, _allowWarnings);
|
||||
auto error = parseAndReturnFirstError(_source, _dialect, _allowWarningsAndInfos);
|
||||
BOOST_REQUIRE(error);
|
||||
return *error;
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ TestCase::TestResult StackLayoutGeneratorTest::run(ostream& _stream, string cons
|
||||
{
|
||||
ErrorList errors;
|
||||
auto [object, analysisInfo] = parse(m_source, *m_dialect, errors);
|
||||
if (!object || !analysisInfo || !Error::containsOnlyWarnings(errors))
|
||||
if (!object || !analysisInfo || Error::containsErrors(errors))
|
||||
{
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << endl;
|
||||
return TestResult::FatalError;
|
||||
|
@ -114,7 +114,7 @@ std::pair<std::shared_ptr<Object>, std::shared_ptr<AsmAnalysisInfo>> YulOptimize
|
||||
shared_ptr<Object> object;
|
||||
shared_ptr<AsmAnalysisInfo> analysisInfo;
|
||||
std::tie(object, analysisInfo) = yul::test::parse(_source, *m_dialect, errors);
|
||||
if (!object || !analysisInfo || !Error::containsOnlyWarnings(errors))
|
||||
if (!object || !analysisInfo || Error::containsErrors(errors))
|
||||
{
|
||||
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << endl;
|
||||
CharStream charStream(_source, "");
|
||||
|
@ -29,7 +29,7 @@ bytes YulAssembler::assemble()
|
||||
!m_stack.parseAndAnalyze("source", m_yulProgram) ||
|
||||
!m_stack.parserResult()->code ||
|
||||
!m_stack.parserResult()->analysisInfo ||
|
||||
!langutil::Error::containsOnlyWarnings(m_stack.errors())
|
||||
langutil::Error::containsErrors(m_stack.errors())
|
||||
)
|
||||
yulAssert(false, "Yul program could not be parsed successfully.");
|
||||
|
||||
|
@ -72,7 +72,7 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
||||
!stack.parseAndAnalyze("source", yul_source) ||
|
||||
!stack.parserResult()->code ||
|
||||
!stack.parserResult()->analysisInfo ||
|
||||
!Error::containsOnlyWarnings(stack.errors())
|
||||
Error::containsErrors(stack.errors())
|
||||
)
|
||||
yulAssert(false, "Proto fuzzer generated malformed program");
|
||||
|
||||
|
@ -71,7 +71,7 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
||||
!stack.parseAndAnalyze("source", yul_source) ||
|
||||
!stack.parserResult()->code ||
|
||||
!stack.parserResult()->analysisInfo ||
|
||||
!Error::containsOnlyWarnings(stack.errors())
|
||||
Error::containsErrors(stack.errors())
|
||||
)
|
||||
{
|
||||
SourceReferenceFormatter formatter(std::cout, stack, false, false);
|
||||
|
Loading…
Reference in New Issue
Block a user