Merge pull request #2507 from ethereum/jsonio-safe

Handle parsing errors in StandardCompiler
This commit is contained in:
chriseth 2017-07-03 13:23:28 +02:00 committed by GitHub
commit 2b233e7388
2 changed files with 17 additions and 14 deletions

View File

@ -77,6 +77,14 @@ enum class DocumentationType: uint8_t
class CompilerStack: boost::noncopyable class CompilerStack: boost::noncopyable
{ {
public: public:
enum State {
Empty,
SourcesSet,
ParsingSuccessful,
AnalysisSuccessful,
CompilationSuccessful
};
/// Creates a new compiler stack. /// Creates a new compiler stack.
/// @param _readFile callback to used to read files for import statements. Must return /// @param _readFile callback to used to read files for import statements. Must return
/// and must not emit exceptions. /// and must not emit exceptions.
@ -194,6 +202,8 @@ public:
/// @returns the list of errors that occured during parsing and type checking. /// @returns the list of errors that occured during parsing and type checking.
ErrorList const& errors() { return m_errorReporter.errors(); } ErrorList const& errors() { return m_errorReporter.errors(); }
State state() const { return m_stackState; }
private: private:
/** /**
* Information pertaining to one source unit, filled gradually during parsing and compilation. * Information pertaining to one source unit, filled gradually during parsing and compilation.
@ -220,14 +230,6 @@ private:
mutable std::unique_ptr<std::string const> sourceMapping; mutable std::unique_ptr<std::string const> sourceMapping;
mutable std::unique_ptr<std::string const> runtimeSourceMapping; mutable std::unique_ptr<std::string const> runtimeSourceMapping;
}; };
enum State {
Empty,
SourcesSet,
ParsingSuccessful,
AnalysisSuccessful,
CompilationSuccessful
};
/// Loads the missing sources from @a _ast (named @a _path) using the callback /// Loads the missing sources from @a _ast (named @a _path) using the callback
/// @a m_readFile and stores the absolute paths of all imports in the AST annotations. /// @a m_readFile and stores the absolute paths of all imports in the AST annotations.
/// @returns the newly loaded sources. /// @returns the newly loaded sources.

View File

@ -265,11 +265,9 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compilerStack.scanner(_sourceName); }; auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compilerStack.scanner(_sourceName); };
bool success = false;
try try
{ {
success = m_compilerStack.compile(optimize, optimizeRuns, libraries); m_compilerStack.compile(optimize, optimizeRuns, libraries);
for (auto const& error: m_compilerStack.errors()) for (auto const& error: m_compilerStack.errors())
{ {
@ -359,13 +357,16 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
if (errors.size() > 0) if (errors.size() > 0)
output["errors"] = errors; output["errors"] = errors;
bool parsingSuccess = m_compilerStack.state() >= CompilerStack::State::ParsingSuccessful;
bool compilationSuccess = m_compilerStack.state() == CompilerStack::State::CompilationSuccessful;
/// Inconsistent state - stop here to receive error reports from users /// Inconsistent state - stop here to receive error reports from users
if (!success && (errors.size() == 0)) if (!compilationSuccess && (errors.size() == 0))
return formatFatalError("InternalCompilerError", "No error reported, but compilation failed."); return formatFatalError("InternalCompilerError", "No error reported, but compilation failed.");
output["sources"] = Json::objectValue; output["sources"] = Json::objectValue;
unsigned sourceIndex = 0; unsigned sourceIndex = 0;
for (auto const& source: m_compilerStack.sourceNames()) for (auto const& source: parsingSuccess ? m_compilerStack.sourceNames() : vector<string>())
{ {
Json::Value sourceResult = Json::objectValue; Json::Value sourceResult = Json::objectValue;
sourceResult["id"] = sourceIndex++; sourceResult["id"] = sourceIndex++;
@ -375,7 +376,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
} }
Json::Value contractsOutput = Json::objectValue; Json::Value contractsOutput = Json::objectValue;
for (string const& contractName: success ? m_compilerStack.contractNames() : vector<string>()) for (string const& contractName: compilationSuccess ? m_compilerStack.contractNames() : vector<string>())
{ {
size_t colon = contractName.find(':'); size_t colon = contractName.find(':');
solAssert(colon != string::npos, ""); solAssert(colon != string::npos, "");