diff options
author | Alex Beregszaszi <alex@rtfs.hu> | 2017-03-30 04:50:53 +0800 |
---|---|---|
committer | Alex Beregszaszi <alex@rtfs.hu> | 2017-04-21 02:38:00 +0800 |
commit | f25efceaf8d168118b2fa8641bd33611bd824d2d (patch) | |
tree | e6123e4f8aeb1b01b1a44100b1c372ba299c4587 /libsolidity/interface | |
parent | b3c6b1e936b3cd10d6a871299fd19fb977c2363a (diff) | |
download | dexon-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.cpp | 122 |
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()) |