aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/interface
diff options
context:
space:
mode:
authorAlex Beregszaszi <alex@rtfs.hu>2017-03-30 04:50:53 +0800
committerAlex Beregszaszi <alex@rtfs.hu>2017-04-21 02:38:00 +0800
commitf25efceaf8d168118b2fa8641bd33611bd824d2d (patch)
treee6123e4f8aeb1b01b1a44100b1c372ba299c4587 /libsolidity/interface
parentb3c6b1e936b3cd10d6a871299fd19fb977c2363a (diff)
downloaddexon-solidity-f25efceaf8d168118b2fa8641bd33611bd824d2d.tar.gz
dexon-solidity-f25efceaf8d168118b2fa8641bd33611bd824d2d.tar.zst
dexon-solidity-f25efceaf8d168118b2fa8641bd33611bd824d2d.zip
Support proper error reporting in StandardCompiler
Diffstat (limited to 'libsolidity/interface')
-rw-r--r--libsolidity/interface/StandardCompiler.cpp122
1 files changed, 104 insertions, 18 deletions
diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp
index 8fa08647..aa14d2b0 100644
--- a/libsolidity/interface/StandardCompiler.cpp
+++ b/libsolidity/interface/StandardCompiler.cpp
@@ -58,6 +58,37 @@ Json::Value formatFatalError(string const& _type, string const& _message)
return output;
}
+Json::Value formatErrorWithException(
+ Exception const& _exception,
+ bool const& _warning,
+ string const& _type,
+ string const& _component,
+ string const& _message,
+ function<Scanner const&(string const&)> const& _scannerFromSourceName
+)
+{
+ string message;
+ string formattedMessage = SourceReferenceFormatter::formatExceptionInformation(_exception, _message, _scannerFromSourceName);
+
+ // NOTE: the below is partially a copy from SourceReferenceFormatter
+ SourceLocation const* location = boost::get_error_info<errinfo_sourceLocation>(_exception);
+
+ if (string const* description = boost::get_error_info<errinfo_comment>(_exception))
+ message = ((_message.length() > 0) ? (_message + ":") : "") + *description;
+ else
+ message = _message;
+
+ if (location && location->sourceName)
+ {
+ Json::Value sourceLocation = Json::objectValue;
+ sourceLocation["file"] = *location->sourceName;
+ sourceLocation["start"] = location->start;
+ sourceLocation["end"] = location->end;
+ }
+
+ return formatError(_warning, _type, _component, message, formattedMessage, location);
+}
+
StringMap createSourceList(Json::Value const& _input)
{
StringMap sources;
@@ -102,50 +133,105 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compilerStack.scanner(_sourceName); };
+ Json::Value errors = Json::arrayValue;
+ bool success = false;
+
try
{
- // @TODO check return value and parse errors
- m_compilerStack.compile(optimize, optimizeRuns, libraries);
+ success = m_compilerStack.compile(optimize, optimizeRuns, libraries);
+
+ for (auto const& error: m_compilerStack.errors())
+ {
+ auto err = dynamic_pointer_cast<Error const>(error);
+
+ errors.append(formatErrorWithException(
+ *error,
+ err->type() == Error::Type::Warning,
+ err->typeName(),
+ "general",
+ "",
+ scannerFromSourceName
+ ));
+ }
}
catch (Error const& _error)
{
if (_error.type() == Error::Type::DocstringParsingError)
- cerr << "Documentation parsing error: " << *boost::get_error_info<errinfo_comment>(_error) << endl;
+ errors.append(formatError(
+ false,
+ "DocstringParsingError",
+ "general",
+ "Documentation parsing error: " + *boost::get_error_info<errinfo_comment>(_error)
+ ));
else
- SourceReferenceFormatter::printExceptionInformation(cerr, _error, _error.typeName(), scannerFromSourceName);
-
- return Json::Value();
+ errors.append(formatErrorWithException(
+ _error,
+ false,
+ _error.typeName(),
+ "general",
+ "",
+ scannerFromSourceName
+ ));
}
catch (CompilerError const& _exception)
{
- SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Compiler error", scannerFromSourceName);
- return Json::Value();
+ errors.append(formatErrorWithException(
+ _exception,
+ false,
+ "CompilerError",
+ "general",
+ "Compiler error (" + _exception.lineInfo() + ")",
+ scannerFromSourceName
+ ));
}
catch (InternalCompilerError const& _exception)
{
- cerr << "Internal compiler error during compilation:" << endl
- << boost::diagnostic_information(_exception);
- return Json::Value();
+ errors.append(formatErrorWithException(
+ _exception,
+ false,
+ "InternalCompilerError",
+ "general",
+ "Internal compiler error (" + _exception.lineInfo() + ")", scannerFromSourceName
+ ));
}
catch (UnimplementedFeatureError const& _exception)
{
- cerr << "Unimplemented feature:" << endl
- << boost::diagnostic_information(_exception);
- return Json::Value();
+ errors.append(formatErrorWithException(
+ _exception,
+ false,
+ "UnimplementedFeatureError",
+ "general",
+ "Unimplemented feature (" + _exception.lineInfo() + ")",
+ scannerFromSourceName));
}
catch (Exception const& _exception)
{
- cerr << "Exception during compilation: " << boost::diagnostic_information(_exception) << endl;
- return Json::Value();
+ errors.append(formatError(
+ false,
+ "Exception",
+ "general",
+ "Exception during compilation: " + boost::diagnostic_information(_exception)
+ ));
}
catch (...)
{
- cerr << "Unknown exception during compilation." << endl;
- return Json::Value();
+ errors.append(formatError(
+ false,
+ "Exception",
+ "general",
+ "Unknown exception during compilation."
+ ));
}
Json::Value output = Json::objectValue;
+ if (errors.size() > 0)
+ output["errors"] = errors;
+
+ /// Inconsistent state - stop here to receive error reports from users
+ if (!success && (errors.size() == 0))
+ return formatFatalError("InternalCompilerError", "No error reported, but compilation failed.");
+
output["sources"] = Json::objectValue;
unsigned sourceIndex = 0;
for (auto const& source: m_compilerStack.sourceNames())