Refactor error reporting

This commit introduces ErrorReporter, a utility class which consolidates
all of the error logging functionality into a common set of functions.
It also replaces all direct interactions with an ErrorList with calls to
an ErrorReporter.

This commit resolves issue #2209
This commit is contained in:
Rhett Aultman
2017-05-30 07:28:31 -07:00
parent 0066a08aa8
commit 89b60ffbd4
47 changed files with 770 additions and 707 deletions
+5 -4
View File
@@ -45,16 +45,16 @@ namespace test
namespace
{
bool parse(string const& _source, ErrorList& errors)
bool parse(string const& _source, ErrorReporter& errorReporter)
{
try
{
auto scanner = make_shared<Scanner>(CharStream(_source));
auto parserResult = assembly::Parser(errors, true).parse(scanner);
auto parserResult = assembly::Parser(errorReporter, true).parse(scanner);
if (parserResult)
{
assembly::AsmAnalysisInfo analysisInfo;
return (assembly::AsmAnalyzer(analysisInfo, errors, true)).analyze(*parserResult);
return (assembly::AsmAnalyzer(analysisInfo, errorReporter, true)).analyze(*parserResult);
}
}
catch (FatalError const&)
@@ -67,7 +67,8 @@ bool parse(string const& _source, ErrorList& errors)
boost::optional<Error> parseAndReturnFirstError(string const& _source, bool _allowWarnings = true)
{
ErrorList errors;
if (!parse(_source, errors))
ErrorReporter errorReporter(errors);
if (!parse(_source, errorReporter))
{
BOOST_REQUIRE_EQUAL(errors.size(), 1);
return *errors.front();
+8 -6
View File
@@ -31,6 +31,7 @@
#include <libsolidity/codegen/Compiler.h>
#include <libsolidity/ast/AST.h>
#include <libsolidity/analysis/TypeChecker.h>
#include <libsolidity/interface/ErrorReporter.h>
using namespace std;
using namespace dev::eth;
@@ -48,28 +49,29 @@ namespace
eth::AssemblyItems compileContract(const string& _sourceCode)
{
ErrorList errors;
Parser parser(errors);
ErrorReporter errorReporter(errors);
Parser parser(errorReporter);
ASTPointer<SourceUnit> sourceUnit;
BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared<Scanner>(CharStream(_sourceCode))));
BOOST_CHECK(!!sourceUnit);
map<ASTNode const*, shared_ptr<DeclarationContainer>> scopes;
NameAndTypeResolver resolver({}, scopes, errors);
solAssert(Error::containsOnlyWarnings(errors), "");
NameAndTypeResolver resolver({}, scopes, errorReporter);
solAssert(Error::containsOnlyWarnings(errorReporter.errors()), "");
resolver.registerDeclarations(*sourceUnit);
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
if (!Error::containsOnlyWarnings(errors))
if (!Error::containsOnlyWarnings(errorReporter.errors()))
return AssemblyItems();
}
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
TypeChecker checker(errors);
TypeChecker checker(errorReporter);
BOOST_REQUIRE_NO_THROW(checker.checkTypeRequirements(*contract));
if (!Error::containsOnlyWarnings(errors))
if (!Error::containsOnlyWarnings(errorReporter.errors()))
return AssemblyItems();
}
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
@@ -29,6 +29,7 @@
#include <libsolidity/codegen/ExpressionCompiler.h>
#include <libsolidity/ast/AST.h>
#include <libsolidity/analysis/TypeChecker.h>
#include <libsolidity/interface/ErrorReporter.h>
#include "../TestHelper.h"
using namespace std;
@@ -98,7 +99,8 @@ bytes compileFirstExpression(
try
{
ErrorList errors;
sourceUnit = Parser(errors).parse(make_shared<Scanner>(CharStream(_sourceCode)));
ErrorReporter errorReporter(errors);
sourceUnit = Parser(errorReporter).parse(make_shared<Scanner>(CharStream(_sourceCode)));
if (!sourceUnit)
return bytes();
}
@@ -114,8 +116,9 @@ bytes compileFirstExpression(
declarations.push_back(variable.get());
ErrorList errors;
ErrorReporter errorReporter(errors);
map<ASTNode const*, shared_ptr<DeclarationContainer>> scopes;
NameAndTypeResolver resolver(declarations, scopes, errors);
NameAndTypeResolver resolver(declarations, scopes, errorReporter);
resolver.registerDeclarations(*sourceUnit);
vector<ContractDefinition const*> inheritanceHierarchy;
@@ -128,7 +131,8 @@ bytes compileFirstExpression(
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
{
TypeChecker typeChecker(errors);
ErrorReporter errorReporter(errors);
TypeChecker typeChecker(errorReporter);
BOOST_REQUIRE(typeChecker.checkTypeRequirements(*contract));
}
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
@@ -30,7 +30,7 @@
#include <libsolidity/analysis/StaticAnalyzer.h>
#include <libsolidity/analysis/PostTypeChecker.h>
#include <libsolidity/analysis/SyntaxChecker.h>
#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/interface/ErrorReporter.h>
#include <libsolidity/analysis/GlobalContext.h>
#include <libsolidity/analysis/TypeChecker.h>
@@ -56,7 +56,8 @@ parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false,
// Silence compiler version warning
string source = _insertVersionPragma ? "pragma solidity >=0.0;\n" + _source : _source;
ErrorList errors;
Parser parser(errors);
ErrorReporter errorReporter(errors);
Parser parser(errorReporter);
ASTPointer<SourceUnit> sourceUnit;
// catch exceptions for a transition period
try
@@ -65,14 +66,14 @@ parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false,
if(!sourceUnit)
BOOST_FAIL("Parsing failed in type checker test.");
SyntaxChecker syntaxChecker(errors);
SyntaxChecker syntaxChecker(errorReporter);
if (!syntaxChecker.checkSyntax(*sourceUnit))
return make_pair(sourceUnit, errors.at(0));
return make_pair(sourceUnit, errorReporter.errors().at(0));
std::shared_ptr<GlobalContext> globalContext = make_shared<GlobalContext>();
map<ASTNode const*, shared_ptr<DeclarationContainer>> scopes;
NameAndTypeResolver resolver(globalContext->declarations(), scopes, errors);
solAssert(Error::containsOnlyWarnings(errors), "");
NameAndTypeResolver resolver(globalContext->declarations(), scopes, errorReporter);
solAssert(Error::containsOnlyWarnings(errorReporter.errors()), "");
resolver.registerDeclarations(*sourceUnit);
bool success = true;
@@ -92,19 +93,19 @@ parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false,
globalContext->setCurrentContract(*contract);
resolver.updateDeclaration(*globalContext->currentThis());
TypeChecker typeChecker(errors);
TypeChecker typeChecker(errorReporter);
bool success = typeChecker.checkTypeRequirements(*contract);
BOOST_CHECK(success || !errors.empty());
BOOST_CHECK(success || !errorReporter.errors().empty());
}
if (success)
if (!PostTypeChecker(errors).check(*sourceUnit))
if (!PostTypeChecker(errorReporter).check(*sourceUnit))
success = false;
if (success)
if (!StaticAnalyzer(errors).analyze(*sourceUnit))
if (!StaticAnalyzer(errorReporter).analyze(*sourceUnit))
success = false;
if (errors.size() > 1 && !_allowMultipleErrors)
if (errorReporter.errors().size() > 1 && !_allowMultipleErrors)
BOOST_FAIL("Multiple errors found");
for (auto const& currentError: errors)
for (auto const& currentError: errorReporter.errors())
{
if (
(_reportWarnings && currentError->type() == Error::Type::Warning) ||
+3 -2
View File
@@ -24,7 +24,7 @@
#include <memory>
#include <libsolidity/parsing/Scanner.h>
#include <libsolidity/parsing/Parser.h>
#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/interface/ErrorReporter.h>
#include "../TestHelper.h"
#include "ErrorCheck.h"
@@ -41,7 +41,8 @@ namespace
{
ASTPointer<ContractDefinition> parseText(std::string const& _source, ErrorList& _errors)
{
ASTPointer<SourceUnit> sourceUnit = Parser(_errors).parse(std::make_shared<Scanner>(CharStream(_source)));
ErrorReporter errorReporter(_errors);
ASTPointer<SourceUnit> sourceUnit = Parser(errorReporter).parse(std::make_shared<Scanner>(CharStream(_source)));
if (!sourceUnit)
return ASTPointer<ContractDefinition>();
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())