aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/interface
diff options
context:
space:
mode:
authorRhett Aultman <roadriverrail@gmail.com>2017-05-11 21:26:35 +0800
committerRhett Aultman <roadriverrail@gmail.com>2017-05-30 22:28:31 +0800
commit89b60ffbd4c2dde26fa5e9f1d750729b5c89373e (patch)
treea4c464d4d40baaa260f071c1028f347bd287e44d /libsolidity/interface
parent0066a08aa8f6c469cde7947ec50ca662a32123a0 (diff)
downloaddexon-solidity-89b60ffbd4c2dde26fa5e9f1d750729b5c89373e.tar
dexon-solidity-89b60ffbd4c2dde26fa5e9f1d750729b5c89373e.tar.gz
dexon-solidity-89b60ffbd4c2dde26fa5e9f1d750729b5c89373e.tar.bz2
dexon-solidity-89b60ffbd4c2dde26fa5e9f1d750729b5c89373e.tar.lz
dexon-solidity-89b60ffbd4c2dde26fa5e9f1d750729b5c89373e.tar.xz
dexon-solidity-89b60ffbd4c2dde26fa5e9f1d750729b5c89373e.tar.zst
dexon-solidity-89b60ffbd4c2dde26fa5e9f1d750729b5c89373e.zip
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
Diffstat (limited to 'libsolidity/interface')
-rw-r--r--libsolidity/interface/AssemblyStack.cpp8
-rw-r--r--libsolidity/interface/AssemblyStack.h5
-rw-r--r--libsolidity/interface/CompilerStack.cpp48
-rw-r--r--libsolidity/interface/CompilerStack.h14
-rw-r--r--libsolidity/interface/ErrorReporter.cpp186
-rw-r--r--libsolidity/interface/ErrorReporter.h106
6 files changed, 328 insertions, 39 deletions
diff --git a/libsolidity/interface/AssemblyStack.cpp b/libsolidity/interface/AssemblyStack.cpp
index c4bd63c4..b027ac3c 100644
--- a/libsolidity/interface/AssemblyStack.cpp
+++ b/libsolidity/interface/AssemblyStack.cpp
@@ -45,13 +45,13 @@ bool AssemblyStack::parseAndAnalyze(std::string const& _sourceName, std::string
{
m_analysisSuccessful = false;
m_scanner = make_shared<Scanner>(CharStream(_source), _sourceName);
- m_parserResult = assembly::Parser(m_errors, m_language == Language::JULIA).parse(m_scanner);
- if (!m_errors.empty())
+ m_parserResult = assembly::Parser(m_errorReporter, m_language == Language::JULIA).parse(m_scanner);
+ if (!m_errorReporter.errors().empty())
return false;
solAssert(m_parserResult, "");
m_analysisInfo = make_shared<assembly::AsmAnalysisInfo>();
- assembly::AsmAnalyzer analyzer(*m_analysisInfo, m_errors);
+ assembly::AsmAnalyzer analyzer(*m_analysisInfo, m_errorReporter);
m_analysisSuccessful = analyzer.analyze(*m_parserResult);
return m_analysisSuccessful;
}
@@ -66,7 +66,7 @@ eth::LinkerObject AssemblyStack::assemble(Machine _machine)
{
case Machine::EVM:
{
- auto assembly = assembly::CodeGenerator(m_errors).assemble(*m_parserResult, *m_analysisInfo);
+ auto assembly = assembly::CodeGenerator(m_errorReporter).assemble(*m_parserResult, *m_analysisInfo);
return assembly.assemble();
}
case Machine::EVM15:
diff --git a/libsolidity/interface/AssemblyStack.h b/libsolidity/interface/AssemblyStack.h
index 40662ac3..62a5134a 100644
--- a/libsolidity/interface/AssemblyStack.h
+++ b/libsolidity/interface/AssemblyStack.h
@@ -21,8 +21,8 @@
#pragma once
-#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/inlineasm/AsmAnalysisInfo.h>
+#include <libsolidity/interface/ErrorReporter.h>
#include <libevmasm/LinkerObject.h>
#include <string>
@@ -50,7 +50,7 @@ public:
enum class Machine { EVM, EVM15, eWasm };
explicit AssemblyStack(Language _language = Language::Assembly):
- m_language(_language)
+ m_language(_language), m_errorReporter(m_errors)
{}
/// @returns the scanner used during parsing
@@ -79,6 +79,7 @@ private:
std::shared_ptr<assembly::Block> m_parserResult;
std::shared_ptr<assembly::AsmAnalysisInfo> m_analysisInfo;
ErrorList m_errors;
+ ErrorReporter m_errorReporter;
};
}
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp
index 328df91f..44220402 100644
--- a/libsolidity/interface/CompilerStack.cpp
+++ b/libsolidity/interface/CompilerStack.cpp
@@ -57,9 +57,6 @@ using namespace std;
using namespace dev;
using namespace dev::solidity;
-CompilerStack::CompilerStack(ReadFile::Callback const& _readFile):
- m_readFile(_readFile) {}
-
void CompilerStack::setRemappings(vector<string> const& _remappings)
{
vector<Remapping> remappings;
@@ -96,7 +93,7 @@ void CompilerStack::reset(bool _keepSources)
m_scopes.clear();
m_sourceOrder.clear();
m_contracts.clear();
- m_errors.clear();
+ m_errorReporter.clear();
m_stackState = Empty;
}
@@ -121,15 +118,11 @@ bool CompilerStack::parse()
//reset
if(m_stackState != SourcesSet)
return false;
- m_errors.clear();
+ m_errorReporter.clear();
ASTNode::resetID();
if (SemVerVersion{string(VersionString)}.isPrerelease())
- {
- auto err = make_shared<Error>(Error::Type::Warning);
- *err << errinfo_comment("This is a pre-release compiler version, please do not use it in production.");
- m_errors.push_back(err);
- }
+ m_errorReporter.warning("This is a pre-release compiler version, please do not use it in production.");
vector<string> sourcesToParse;
for (auto const& s: m_sources)
@@ -139,9 +132,9 @@ bool CompilerStack::parse()
string const& path = sourcesToParse[i];
Source& source = m_sources[path];
source.scanner->reset();
- source.ast = Parser(m_errors).parse(source.scanner);
+ source.ast = Parser(m_errorReporter).parse(source.scanner);
if (!source.ast)
- solAssert(!Error::containsOnlyWarnings(m_errors), "Parser returned null but did not report error.");
+ solAssert(!Error::containsOnlyWarnings(m_errorReporter.errors()), "Parser returned null but did not report error.");
else
{
source.ast->annotation().path = path;
@@ -154,7 +147,7 @@ bool CompilerStack::parse()
}
}
}
- if (Error::containsOnlyWarnings(m_errors))
+ if (Error::containsOnlyWarnings(m_errorReporter.errors()))
{
m_stackState = ParsingSuccessful;
return true;
@@ -170,18 +163,18 @@ bool CompilerStack::analyze()
resolveImports();
bool noErrors = true;
- SyntaxChecker syntaxChecker(m_errors);
+ SyntaxChecker syntaxChecker(m_errorReporter);
for (Source const* source: m_sourceOrder)
if (!syntaxChecker.checkSyntax(*source->ast))
noErrors = false;
- DocStringAnalyser docStringAnalyser(m_errors);
+ DocStringAnalyser docStringAnalyser(m_errorReporter);
for (Source const* source: m_sourceOrder)
if (!docStringAnalyser.analyseDocStrings(*source->ast))
noErrors = false;
m_globalContext = make_shared<GlobalContext>();
- NameAndTypeResolver resolver(m_globalContext->declarations(), m_scopes, m_errors);
+ NameAndTypeResolver resolver(m_globalContext->declarations(), m_scopes, m_errorReporter);
for (Source const* source: m_sourceOrder)
if (!resolver.registerDeclarations(*source->ast))
return false;
@@ -217,7 +210,7 @@ bool CompilerStack::analyze()
{
m_globalContext->setCurrentContract(*contract);
resolver.updateDeclaration(*m_globalContext->currentThis());
- TypeChecker typeChecker(m_errors);
+ TypeChecker typeChecker(m_errorReporter);
if (typeChecker.checkTypeRequirements(*contract))
{
contract->setDevDocumentation(Natspec::devDocumentation(*contract));
@@ -237,7 +230,7 @@ bool CompilerStack::analyze()
if (noErrors)
{
- PostTypeChecker postTypeChecker(m_errors);
+ PostTypeChecker postTypeChecker(m_errorReporter);
for (Source const* source: m_sourceOrder)
if (!postTypeChecker.check(*source->ast))
noErrors = false;
@@ -245,7 +238,7 @@ bool CompilerStack::analyze()
if (noErrors)
{
- StaticAnalyzer staticAnalyzer(m_errors);
+ StaticAnalyzer staticAnalyzer(m_errorReporter);
for (Source const* source: m_sourceOrder)
if (!staticAnalyzer.analyze(*source->ast))
noErrors = false;
@@ -323,11 +316,11 @@ void CompilerStack::link()
}
}
-bool CompilerStack::prepareFormalAnalysis(ErrorList* _errors)
+bool CompilerStack::prepareFormalAnalysis(ErrorReporter* _errorReporter)
{
- if (!_errors)
- _errors = &m_errors;
- Why3Translator translator(*_errors);
+ if (!_errorReporter)
+ _errorReporter = &m_errorReporter;
+ Why3Translator translator(*_errorReporter);
for (Source const* source: m_sourceOrder)
if (!translator.process(*source->ast))
return false;
@@ -582,11 +575,10 @@ StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast, std::string
newSources[importPath] = result.contentsOrErrorMessage;
else
{
- auto err = make_shared<Error>(Error::Type::ParserError);
- *err <<
- errinfo_sourceLocation(import->location()) <<
- errinfo_comment("Source \"" + importPath + "\" not found: " + result.contentsOrErrorMessage);
- m_errors.push_back(std::move(err));
+ m_errorReporter.parserError(
+ import->location(),
+ string("Source \"" + importPath + "\" not found: " + result.contentsOrErrorMessage)
+ );
continue;
}
}
diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h
index 84d15d70..76d36c7b 100644
--- a/libsolidity/interface/CompilerStack.h
+++ b/libsolidity/interface/CompilerStack.h
@@ -35,7 +35,7 @@
#include <libdevcore/FixedHash.h>
#include <libevmasm/SourceLocation.h>
#include <libevmasm/LinkerObject.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <libsolidity/interface/ErrorReporter.h>
#include <libsolidity/interface/ReadFile.h>
namespace dev
@@ -80,7 +80,10 @@ public:
/// Creates a new compiler stack.
/// @param _readFile callback to used to read files for import statements. Must return
/// and must not emit exceptions.
- explicit CompilerStack(ReadFile::Callback const& _readFile = ReadFile::Callback());
+ explicit CompilerStack(ReadFile::Callback const& _readFile = ReadFile::Callback()):
+ m_readFile(_readFile),
+ m_errorList(),
+ m_errorReporter(m_errorList) {}
/// Sets path remappings in the format "context:prefix=target"
void setRemappings(std::vector<std::string> const& _remappings);
@@ -130,7 +133,7 @@ public:
/// Tries to translate all source files into a language suitable for formal analysis.
/// @param _errors list to store errors - defaults to the internal error list.
/// @returns false on error.
- bool prepareFormalAnalysis(ErrorList* _errors = nullptr);
+ bool prepareFormalAnalysis(ErrorReporter* _errorReporter = nullptr);
std::string const& formalTranslation() const { return m_formalTranslation; }
/// @returns the assembled object for a contract.
@@ -207,7 +210,7 @@ public:
std::tuple<int, int, int, int> positionFromSourceLocation(SourceLocation const& _sourceLocation) const;
/// @returns the list of errors that occured during parsing and type checking.
- ErrorList const& errors() const { return m_errors; }
+ ErrorList const& errors() { return m_errorReporter.errors(); }
private:
/**
@@ -289,7 +292,8 @@ private:
std::vector<Source const*> m_sourceOrder;
std::map<std::string const, Contract> m_contracts;
std::string m_formalTranslation;
- ErrorList m_errors;
+ ErrorList m_errorList;
+ ErrorReporter m_errorReporter;
bool m_metadataLiteralSources = false;
State m_stackState = Empty;
};
diff --git a/libsolidity/interface/ErrorReporter.cpp b/libsolidity/interface/ErrorReporter.cpp
new file mode 100644
index 00000000..2cbb952c
--- /dev/null
+++ b/libsolidity/interface/ErrorReporter.cpp
@@ -0,0 +1,186 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @author Rhett <roadriverrail@gmail.com>
+ * @date 2017
+ * Error helper class.
+ */
+
+#include <libsolidity/interface/ErrorReporter.h>
+#include <libsolidity/ast/AST.h>
+#include <memory>
+
+using namespace std;
+using namespace dev;
+using namespace dev::solidity;
+
+ErrorReporter& ErrorReporter::operator=(ErrorReporter const& _errorReporter)
+{
+ if (&_errorReporter == this)
+ return *this;
+ m_errorList = _errorReporter.m_errorList;
+ return *this;
+}
+
+
+void ErrorReporter::warning(string const& _description)
+{
+ error(Error::Type::Warning, SourceLocation(), _description);
+}
+
+void ErrorReporter::warning(SourceLocation const& _location, string const& _description)
+{
+ error(Error::Type::Warning, _location, _description);
+}
+
+void ErrorReporter::error(Error::Type _type, SourceLocation const& _location, string const& _description)
+{
+ auto err = make_shared<Error>(_type);
+ *err <<
+ errinfo_sourceLocation(_location) <<
+ errinfo_comment(_description);
+
+ m_errorList.push_back(err);
+}
+
+void ErrorReporter::error(Error::Type _type, SourceLocation const& _location, SecondarySourceLocation const& _secondaryLocation, string const& _description)
+{
+ auto err = make_shared<Error>(_type);
+ *err <<
+ errinfo_sourceLocation(_location) <<
+ errinfo_secondarySourceLocation(_secondaryLocation) <<
+ errinfo_comment(_description);
+
+ m_errorList.push_back(err);
+}
+
+
+void ErrorReporter::fatalError(Error::Type _type, SourceLocation const& _location, string const& _description)
+{
+ error(_type, _location, _description);
+ BOOST_THROW_EXCEPTION(FatalError());
+}
+
+ErrorList const& ErrorReporter::errors() const
+{
+ return m_errorList;
+}
+
+void ErrorReporter::clear()
+{
+ m_errorList.clear();
+}
+
+void ErrorReporter::declarationError(SourceLocation const& _location, SecondarySourceLocation const&_secondaryLocation, string const& _description)
+{
+ error(
+ Error::Type::DeclarationError,
+ _location,
+ _secondaryLocation,
+ _description
+ );
+}
+
+void ErrorReporter::declarationError(SourceLocation const& _location, string const& _description)
+{
+ error(
+ Error::Type::DeclarationError,
+ _location,
+ _description
+ );
+}
+
+void ErrorReporter::fatalDeclarationError(SourceLocation const& _location, std::string const& _description)
+{
+ fatalError(
+ Error::Type::DeclarationError,
+ _location,
+ _description);
+}
+
+void ErrorReporter::parserError(SourceLocation const& _location, string const& _description)
+{
+ error(
+ Error::Type::ParserError,
+ _location,
+ _description
+ );
+}
+
+void ErrorReporter::fatalParserError(SourceLocation const& _location, string const& _description)
+{
+ fatalError(
+ Error::Type::ParserError,
+ _location,
+ _description
+ );
+}
+
+void ErrorReporter::syntaxError(SourceLocation const& _location, string const& _description)
+{
+ error(
+ Error::Type::SyntaxError,
+ _location,
+ _description
+ );
+}
+
+void ErrorReporter::typeError(SourceLocation const& _location, string const& _description)
+{
+ error(
+ Error::Type::TypeError,
+ _location,
+ _description
+ );
+}
+
+
+void ErrorReporter::fatalTypeError(SourceLocation const& _location, string const& _description)
+{
+ fatalError(Error::Type::TypeError,
+ _location,
+ _description
+ );
+}
+
+void ErrorReporter::docstringParsingError(string const& _description)
+{
+ error(
+ Error::Type::DocstringParsingError,
+ SourceLocation(),
+ _description
+ );
+}
+
+void ErrorReporter::why3TranslatorError(ASTNode const& _location, std::string const& _description)
+{
+ error(
+ Error::Type::Why3TranslatorError,
+ _location.location(),
+ _description
+ );
+}
+
+void ErrorReporter::fatalWhy3TranslatorError(ASTNode const& _location, std::string const& _description)
+{
+ fatalError(
+ Error::Type::Why3TranslatorError,
+ _location.location(),
+ _description
+ );
+}
+
diff --git a/libsolidity/interface/ErrorReporter.h b/libsolidity/interface/ErrorReporter.h
new file mode 100644
index 00000000..83324446
--- /dev/null
+++ b/libsolidity/interface/ErrorReporter.h
@@ -0,0 +1,106 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @author Rhett <roadriverrail@gmail.com>
+ * @date 2017
+ * Error reporting helper class.
+ */
+
+#pragma once
+
+#include <libsolidity/interface/Exceptions.h>
+#include <libevmasm/SourceLocation.h>
+
+namespace dev
+{
+namespace solidity
+{
+
+class ASTNode;
+
+class ErrorReporter
+{
+public:
+
+ ErrorReporter(ErrorList& _errors):
+ m_errorList(_errors) { }
+
+ ErrorReporter& operator=(ErrorReporter const& _errorReporter);
+
+ void warning(std::string const& _description = std::string());
+
+ void warning(
+ SourceLocation const& _location = SourceLocation(),
+ std::string const& _description = std::string()
+ );
+
+ void error(
+ Error::Type _type,
+ SourceLocation const& _location = SourceLocation(),
+ std::string const& _description = std::string()
+ );
+
+ void declarationError(
+ SourceLocation const& _location,
+ SecondarySourceLocation const& _secondaryLocation = SecondarySourceLocation(),
+ std::string const& _description = std::string()
+ );
+
+ void declarationError(
+ SourceLocation const& _location,
+ std::string const& _description = std::string()
+ );
+
+ void fatalDeclarationError(SourceLocation const& _location, std::string const& _description);
+
+ void parserError(SourceLocation const& _location, std::string const& _description);
+
+ void fatalParserError(SourceLocation const& _location, std::string const& _description);
+
+ void syntaxError(SourceLocation const& _location, std::string const& _description);
+
+ void typeError(SourceLocation const& _location, std::string const& _description);
+
+ void fatalTypeError(SourceLocation const& _location, std::string const& _description);
+
+ void docstringParsingError(std::string const& _location);
+
+ void why3TranslatorError(ASTNode const& _location, std::string const& _description);
+
+ void fatalWhy3TranslatorError(ASTNode const& _location, std::string const& _description);
+
+ ErrorList const& errors() const;
+
+ void clear();
+
+private:
+ void error(Error::Type _type,
+ SourceLocation const& _location,
+ SecondarySourceLocation const& _secondaryLocation,
+ std::string const& _description = std::string());
+
+ void fatalError(Error::Type _type,
+ SourceLocation const& _location = SourceLocation(),
+ std::string const& _description = std::string());
+
+ ErrorList& m_errorList;
+};
+
+
+}
+}
+