From 5754b13b473ac9bcd712527991226fe2c92ec46a Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 9 Feb 2017 21:56:49 +0000 Subject: Add StandardCompiler skeleton --- libsolidity/interface/StandardCompiler.cpp | 31 ++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 libsolidity/interface/StandardCompiler.cpp (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp new file mode 100644 index 00000000..98484324 --- /dev/null +++ b/libsolidity/interface/StandardCompiler.cpp @@ -0,0 +1,31 @@ +/* + 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 . +*/ +/** + * @author Alex Beregszaszi + * @date 2016 + * Standard JSON compiler interface. + */ + +#include + +using namespace std; +using namespace dev; +using namespace dev::solidity; + +string StandardCompiler::compile(string const& _input) +{ +} -- cgit v1.2.3 From 985db17e1eb74badb02d2ea6ba23b0d1e7dbc969 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 10 Feb 2017 13:18:21 +0000 Subject: Initial implementation of StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 132 +++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 98484324..acc5642b 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -21,11 +21,143 @@ */ #include +#include +#include +#include using namespace std; using namespace dev; using namespace dev::solidity; +Json::Value StandardCompiler::compile(Json::Value const& _input) +{ + m_compilerStack.reset(false); + + Json::Value const& sources = _input["sources"]; + if (!sources) + { + // @TODO report error + return Json::Value(); + } + + for (auto const& sourceName: sources.getMemberNames()) + m_compilerStack.addSource(sourceName, sources[sourceName]["content"].asString()); + + // @TODO parse settings + bool optimize = false; + unsigned optimizeRuns = 200; + map libraries; + + auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compilerStack.scanner(_sourceName); }; + + try + { + // @TODO check return value and parse errors + m_compilerStack.compile(optimize, optimizeRuns, libraries); + } + catch (Error const& _error) + { + if (_error.type() == Error::Type::DocstringParsingError) + cerr << "Documentation parsing error: " << *boost::get_error_info(_error) << endl; + else + SourceReferenceFormatter::printExceptionInformation(cerr, _error, _error.typeName(), scannerFromSourceName); + + return Json::Value(); + } + catch (CompilerError const& _exception) + { + SourceReferenceFormatter::printExceptionInformation(cerr, _exception, "Compiler error", scannerFromSourceName); + return Json::Value(); + } + catch (InternalCompilerError const& _exception) + { + cerr << "Internal compiler error during compilation:" << endl + << boost::diagnostic_information(_exception); + return Json::Value(); + } + catch (UnimplementedFeatureError const& _exception) + { + cerr << "Unimplemented feature:" << endl + << boost::diagnostic_information(_exception); + return Json::Value(); + } + catch (Exception const& _exception) + { + cerr << "Exception during compilation: " << boost::diagnostic_information(_exception) << endl; + return Json::Value(); + } + catch (...) + { + cerr << "Unknown exception during compilation." << endl; + return Json::Value(); + } + + Json::Value output = Json::objectValue; + + Json::Value contractsOutput = Json::objectValue; + for (string const& contractName: m_compilerStack.contractNames()) + { + // ABI, documentation and metadata + Json::Value contractData(Json::objectValue); + contractData["abi"] = dev::jsonCompactPrint(m_compilerStack.metadata(contractName, DocumentationType::ABIInterface)); + contractData["metadata"] = m_compilerStack.onChainMetadata(contractName); + contractData["userdoc"] = dev::jsonCompactPrint(m_compilerStack.metadata(contractName, DocumentationType::NatspecUser)); + contractData["devdoc"] = dev::jsonCompactPrint(m_compilerStack.metadata(contractName, DocumentationType::NatspecDev)); + + // EVM + Json::Value evmData(Json::objectValue); + // @TODO: add ir + // @TODO: add assembly + // @TODO: add legacyAssemblyJSON + evmData["opcodes"] = solidity::disassemble(m_compilerStack.object(contractName).bytecode); + // @TODO: add methodIdentifiers + // @TODO: add gasEstimates + + // EVM bytecode + Json::Value bytecode(Json::objectValue); + bytecode["object"] = m_compilerStack.object(contractName).toHex(); + auto sourceMap = m_compilerStack.sourceMapping(contractName); + bytecode["sourceMap"] = sourceMap ? *sourceMap : ""; + // @TODO: add linkReferences + evmData["bytecode"] = bytecode; + + // EVM deployed bytecode + Json::Value deployedBytecode(Json::objectValue); + deployedBytecode["object"] = m_compilerStack.runtimeObject(contractName).toHex(); + auto runtimeSourceMap = m_compilerStack.runtimeSourceMapping(contractName); + deployedBytecode["sourceMap"] = runtimeSourceMap ? *runtimeSourceMap : ""; + // @TODO: add linkReferences + evmData["deployedBytecode"] = deployedBytecode; + + contractData["evm"] = evmData; + + contractsOutput[contractName] = contractData; + } + output["contracts"] = Json::objectValue; + output["contracts"][""] = contractsOutput; + + return output; +} + string StandardCompiler::compile(string const& _input) { + Json::Value input; + + if (!Json::Reader().parse(_input, input, false)) + { + return "{\"errors\":\"[{\"type\":\"JSONError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Error parsing input JSON.\"}]}"; + } + + // cout << "Input: " << input.toStyledString() << endl; + Json::Value output = compile(input); + // cout << "Output: " << output.toStyledString() << endl; + + try + { + return jsonCompactPrint(output); + } + catch(...) + { + return "{\"errors\":\"[{\"type\":\"JSONError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Error writing output JSON.\"}]}"; + } } -- cgit v1.2.3 From 418759ece046798d9c1707bb9992aa43ba194303 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 17 Mar 2017 12:08:12 +0000 Subject: Catch exceptions of StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index acc5642b..7f3b7a58 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -29,7 +29,7 @@ using namespace std; using namespace dev; using namespace dev::solidity; -Json::Value StandardCompiler::compile(Json::Value const& _input) +Json::Value StandardCompiler::compileInternal(Json::Value const& _input) { m_compilerStack.reset(false); @@ -139,6 +139,18 @@ Json::Value StandardCompiler::compile(Json::Value const& _input) return output; } +Json::Value StandardCompiler::compile(Json::Value const& _input) +{ + try + { + return compileInternal(_input); + } + catch (...) + { + return "{\"errors\":\"[{\"type\":\"InternalCompilerError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Internal exception in StandardCompiler::compilerInternal\"}]}"; + } +} + string StandardCompiler::compile(string const& _input) { Json::Value input; -- cgit v1.2.3 From 13fa440d37582f80a144b3848340fceb5c55e88d Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 17 Mar 2017 12:29:57 +0000 Subject: Parse optimizer settings in StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 7f3b7a58..88e3b111 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -43,9 +43,12 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) for (auto const& sourceName: sources.getMemberNames()) m_compilerStack.addSource(sourceName, sources[sourceName]["content"].asString()); - // @TODO parse settings - bool optimize = false; - unsigned optimizeRuns = 200; + Json::Value const& settings = _input.get("settings", Json::Value()); + + Json::Value optimizerSettings = settings.get("optimizer", Json::Value()); + bool optimize = optimizerSettings.get("enabled", Json::Value(false)).asBool(); + unsigned optimizeRuns = optimizerSettings.get("runs", Json::Value(200u)).asUInt(); + map libraries; auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compilerStack.scanner(_sourceName); }; -- cgit v1.2.3 From 81775b2df6e624ee9b09f7405d8c0d912d873e5b Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 17 Mar 2017 12:30:29 +0000 Subject: Parse libraries in StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 88e3b111..fd697716 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -50,6 +50,14 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) unsigned optimizeRuns = optimizerSettings.get("runs", Json::Value(200u)).asUInt(); map libraries; + Json::Value jsonLibraries = settings.get("libraries", Json::Value()); + for (auto const& sourceName: jsonLibraries.getMemberNames()) + { + auto const& jsonSourceName = jsonLibraries[sourceName]; + for (auto const& library: jsonSourceName.getMemberNames()) + // @TODO use libraries only for the given source + libraries[library] = h160(jsonSourceName[library].asString()); + } auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compilerStack.scanner(_sourceName); }; -- cgit v1.2.3 From ce87984cc1d3b6f9e1784da831dbdf008853c2c6 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 17 Mar 2017 12:30:50 +0000 Subject: Parse remappings in StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index fd697716..444ce02e 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -45,6 +45,11 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) Json::Value const& settings = _input.get("settings", Json::Value()); + vector remappings; + for (auto const& remapping: settings.get("remappings", Json::Value())) + remappings.push_back(remapping.asString()); + m_compilerStack.setRemappings(remappings); + Json::Value optimizerSettings = settings.get("optimizer", Json::Value()); bool optimize = optimizerSettings.get("enabled", Json::Value(false)).asBool(); unsigned optimizeRuns = optimizerSettings.get("runs", Json::Value(200u)).asUInt(); -- cgit v1.2.3 From f8cb0766d4da0c651999a9e6b9b158216b0a47cb Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 21 Mar 2017 11:18:00 +0000 Subject: Add formatFatalError() to StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 444ce02e..e5de39a8 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -29,6 +29,21 @@ using namespace std; using namespace dev; using namespace dev::solidity; +Json::Value formatFatalError(string const& _type, string const& _description) +{ + Json::Value error = Json::objectValue; + error["type"] = _type; + error["component"] = "general"; + error["severity"] = "error"; + error["message"] = _description; + + Json::Value output = Json::objectValue; + output["errors"] = Json::arrayValue; + output["errors"].append(error); + + return output; +} + Json::Value StandardCompiler::compileInternal(Json::Value const& _input) { m_compilerStack.reset(false); -- cgit v1.2.3 From 4eaee772b3b4afab9d47ab50327fe451ebff22f4 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 29 Mar 2017 13:34:16 +0100 Subject: Capture error messages from the JSON parser --- libsolidity/interface/StandardCompiler.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index e5de39a8..c6a83bab 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -178,15 +178,21 @@ Json::Value StandardCompiler::compile(Json::Value const& _input) } catch (...) { - return "{\"errors\":\"[{\"type\":\"InternalCompilerError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Internal exception in StandardCompiler::compilerInternal\"}]}"; + return formatFatalError("InternalCompilerError", "Internal exception in StandardCompiler::compilerInternal"); } } string StandardCompiler::compile(string const& _input) { Json::Value input; + Json::Reader reader; - if (!Json::Reader().parse(_input, input, false)) + try + { + if (!reader.parse(_input, input, false)) + return jsonCompactPrint(formatFatalError("JSONError", reader.getFormattedErrorMessages())); + } + catch(...) { return "{\"errors\":\"[{\"type\":\"JSONError\",\"component\":\"general\",\"severity\":\"error\",\"message\":\"Error parsing input JSON.\"}]}"; } -- cgit v1.2.3 From 115458c50eec4dc32fdbfe5847fca4134a470668 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 29 Mar 2017 14:29:30 +0100 Subject: Output legacyAssembly in StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index c6a83bab..390332e8 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -44,6 +44,16 @@ Json::Value formatFatalError(string const& _type, string const& _description) return output; } +StringMap createSourceList(Json::Value const& _input) +{ + StringMap sources; + Json::Value const& jsonSources = _input["sources"]; + if (jsonSources.isObject()) + for (auto const& sourceName: jsonSources.getMemberNames()) + sources[sourceName] = jsonSources[sourceName]["content"].asString(); + return sources; +} + Json::Value StandardCompiler::compileInternal(Json::Value const& _input) { m_compilerStack.reset(false); @@ -139,7 +149,8 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) Json::Value evmData(Json::objectValue); // @TODO: add ir // @TODO: add assembly - // @TODO: add legacyAssemblyJSON + ostringstream unused; + evmData["legacyAssembly"] = m_compilerStack.streamAssembly(unused, contractName, createSourceList(_input), true); evmData["opcodes"] = solidity::disassemble(m_compilerStack.object(contractName).bytecode); // @TODO: add methodIdentifiers // @TODO: add gasEstimates -- cgit v1.2.3 From 50bb24af5e84b9fea7fa4132227c9ce2462dede6 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 29 Mar 2017 14:54:34 +0100 Subject: Include source mapping identifier --- libsolidity/interface/StandardCompiler.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 390332e8..82a4ce7b 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -135,6 +135,16 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) Json::Value output = Json::objectValue; + output["sources"] = Json::objectValue; + unsigned sourceIndex = 0; + for (auto const& source: m_compilerStack.sourceNames()) + { + Json::Value sourceResult = Json::objectValue; + sourceResult["id"] = sourceIndex++; + // @TODO add ast + output["sources"][source] = sourceResult; + } + Json::Value contractsOutput = Json::objectValue; for (string const& contractName: m_compilerStack.contractNames()) { -- cgit v1.2.3 From 5aec120da345fc5e59cf3847d3947b34ee0a54a7 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 29 Mar 2017 14:59:00 +0100 Subject: Support the AST output --- libsolidity/interface/StandardCompiler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 82a4ce7b..d78a9487 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -141,7 +142,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) { Json::Value sourceResult = Json::objectValue; sourceResult["id"] = sourceIndex++; - // @TODO add ast + sourceResult["ast"] = ASTJsonConverter(m_compilerStack.ast(source), m_compilerStack.sourceIndices()).json(); output["sources"][source] = sourceResult; } -- cgit v1.2.3 From 2c15e2b5412d0eff4b06ed0a44b1d5fdc219258b Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 29 Mar 2017 15:19:10 +0100 Subject: Fail if no sources are given --- libsolidity/interface/StandardCompiler.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index d78a9487..7fb715bf 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -61,10 +61,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) Json::Value const& sources = _input["sources"]; if (!sources) - { - // @TODO report error - return Json::Value(); - } + return formatFatalError("JSONError", "No input sources specified."); for (auto const& sourceName: sources.getMemberNames()) m_compilerStack.addSource(sourceName, sources[sourceName]["content"].asString()); -- cgit v1.2.3 From b3c6b1e936b3cd10d6a871299fd19fb977c2363a Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 29 Mar 2017 15:40:15 +0100 Subject: Refactor formatError --- libsolidity/interface/StandardCompiler.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 7fb715bf..8fa08647 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -30,18 +30,31 @@ using namespace std; using namespace dev; using namespace dev::solidity; -Json::Value formatFatalError(string const& _type, string const& _description) +Json::Value formatError( + bool _warning, + string const& _type, + string const& _component, + string const& _message, + string const& _formattedMessage = "", + Json::Value const& _sourceLocation = Json::Value() +) { Json::Value error = Json::objectValue; error["type"] = _type; - error["component"] = "general"; - error["severity"] = "error"; - error["message"] = _description; + error["component"] = _component; + error["severity"] = _warning ? "warning" : "error"; + error["message"] = _message; + error["formattedMessage"] = (_formattedMessage.length() > 0) ? _formattedMessage : _message; + if (_sourceLocation.isObject()) + error["sourceLocation"] = _sourceLocation; + return error; +} +Json::Value formatFatalError(string const& _type, string const& _message) +{ Json::Value output = Json::objectValue; output["errors"] = Json::arrayValue; - output["errors"].append(error); - + output["errors"].append(formatError(false, _type, "general", _message)); return output; } -- cgit v1.2.3 From f25efceaf8d168118b2fa8641bd33611bd824d2d Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 29 Mar 2017 21:50:53 +0100 Subject: Support proper error reporting in StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 122 ++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 18 deletions(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') 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 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(_exception); + + if (string const* description = boost::get_error_info(_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); + + 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(_error) << endl; + errors.append(formatError( + false, + "DocstringParsingError", + "general", + "Documentation parsing error: " + *boost::get_error_info(_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()) -- cgit v1.2.3 From 63b6d0099f0a8c0aa8f4bd6e8f19c50f063630fd Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 29 Mar 2017 22:00:38 +0100 Subject: Support methodIdentifiers --- libsolidity/interface/StandardCompiler.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index aa14d2b0..9e425d36 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -99,6 +99,14 @@ StringMap createSourceList(Json::Value const& _input) return sources; } +Json::Value methodIdentifiers(ContractDefinition const& _contract) +{ + Json::Value methodIdentifiers(Json::objectValue); + for (auto const& it: _contract.interfaceFunctions()) + methodIdentifiers[it.second->externalSignature()] = toHex(it.first.ref()); + return methodIdentifiers; +} + Json::Value StandardCompiler::compileInternal(Json::Value const& _input) { m_compilerStack.reset(false); @@ -259,7 +267,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) ostringstream unused; evmData["legacyAssembly"] = m_compilerStack.streamAssembly(unused, contractName, createSourceList(_input), true); evmData["opcodes"] = solidity::disassemble(m_compilerStack.object(contractName).bytecode); - // @TODO: add methodIdentifiers + evmData["methodIdentifiers"] = methodIdentifiers(m_compilerStack.contractDefinition(contractName)); // @TODO: add gasEstimates // EVM bytecode -- cgit v1.2.3 From a87dd17d0f485ae2738371020774fda68644ecea Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 29 Mar 2017 22:07:58 +0100 Subject: Move opcodes inside the bytecode section --- libsolidity/interface/StandardCompiler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 9e425d36..e12b6444 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -266,13 +266,13 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) // @TODO: add assembly ostringstream unused; evmData["legacyAssembly"] = m_compilerStack.streamAssembly(unused, contractName, createSourceList(_input), true); - evmData["opcodes"] = solidity::disassemble(m_compilerStack.object(contractName).bytecode); evmData["methodIdentifiers"] = methodIdentifiers(m_compilerStack.contractDefinition(contractName)); // @TODO: add gasEstimates // EVM bytecode Json::Value bytecode(Json::objectValue); bytecode["object"] = m_compilerStack.object(contractName).toHex(); + bytecode["opcodes"] = solidity::disassemble(m_compilerStack.object(contractName).bytecode); auto sourceMap = m_compilerStack.sourceMapping(contractName); bytecode["sourceMap"] = sourceMap ? *sourceMap : ""; // @TODO: add linkReferences @@ -281,6 +281,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) // EVM deployed bytecode Json::Value deployedBytecode(Json::objectValue); deployedBytecode["object"] = m_compilerStack.runtimeObject(contractName).toHex(); + deployedBytecode["opcodes"] = solidity::disassemble(m_compilerStack.runtimeObject(contractName).bytecode); auto runtimeSourceMap = m_compilerStack.runtimeSourceMapping(contractName); deployedBytecode["sourceMap"] = runtimeSourceMap ? *runtimeSourceMap : ""; // @TODO: add linkReferences -- cgit v1.2.3 From 2df52edfbdc11375b26b6f425529b6b808d19f61 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 30 Mar 2017 00:54:32 +0100 Subject: Support new assembly output --- libsolidity/interface/StandardCompiler.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index e12b6444..ada89dc3 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -263,9 +263,10 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) // EVM Json::Value evmData(Json::objectValue); // @TODO: add ir - // @TODO: add assembly - ostringstream unused; - evmData["legacyAssembly"] = m_compilerStack.streamAssembly(unused, contractName, createSourceList(_input), true); + ostringstream tmp; + m_compilerStack.streamAssembly(tmp, contractName, createSourceList(_input), false); + evmData["assembly"] = tmp.str(); + evmData["legacyAssembly"] = m_compilerStack.streamAssembly(tmp, contractName, createSourceList(_input), true); evmData["methodIdentifiers"] = methodIdentifiers(m_compilerStack.contractDefinition(contractName)); // @TODO: add gasEstimates -- cgit v1.2.3 From ad1fe865088cdb4f97b3728e00d3fc2a5a34aba5 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 30 Mar 2017 02:09:42 +0100 Subject: Support linkReferences --- libsolidity/interface/StandardCompiler.cpp | 31 ++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index ada89dc3..0297a5ec 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -107,6 +107,33 @@ Json::Value methodIdentifiers(ContractDefinition const& _contract) return methodIdentifiers; } +Json::Value formatLinkReferences(std::map const& linkReferences) +{ + Json::Value ret(Json::objectValue); + + for (auto const& ref: linkReferences) + { + string const& fullname = ref.second; + size_t colon = fullname.find(':'); + solAssert(colon != string::npos, ""); + string file = fullname.substr(0, colon); + string name = fullname.substr(colon + 1); + + Json::Value fileObject = ret.get(file, Json::objectValue); + Json::Value libraryArray = fileObject.get(name, Json::arrayValue); + + Json::Value entry = Json::objectValue; + entry["start"] = Json::UInt(ref.first); + entry["length"] = 20; + + libraryArray.append(entry); + fileObject[name] = libraryArray; + ret[file] = fileObject; + } + + return ret; +} + Json::Value StandardCompiler::compileInternal(Json::Value const& _input) { m_compilerStack.reset(false); @@ -276,7 +303,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) bytecode["opcodes"] = solidity::disassemble(m_compilerStack.object(contractName).bytecode); auto sourceMap = m_compilerStack.sourceMapping(contractName); bytecode["sourceMap"] = sourceMap ? *sourceMap : ""; - // @TODO: add linkReferences + bytecode["linkReferences"] = formatLinkReferences(m_compilerStack.object(contractName).linkReferences); evmData["bytecode"] = bytecode; // EVM deployed bytecode @@ -285,7 +312,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) deployedBytecode["opcodes"] = solidity::disassemble(m_compilerStack.runtimeObject(contractName).bytecode); auto runtimeSourceMap = m_compilerStack.runtimeSourceMapping(contractName); deployedBytecode["sourceMap"] = runtimeSourceMap ? *runtimeSourceMap : ""; - // @TODO: add linkReferences + deployedBytecode["linkReferences"] = formatLinkReferences(m_compilerStack.runtimeObject(contractName).linkReferences); evmData["deployedBytecode"] = deployedBytecode; contractData["evm"] = evmData; -- cgit v1.2.3 From ef559de84f1ee87225ac41f61f37dd9e17acc424 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 30 Mar 2017 02:32:43 +0100 Subject: Properly split contract filename and name --- libsolidity/interface/StandardCompiler.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 0297a5ec..13f82f60 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -280,6 +280,11 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) Json::Value contractsOutput = Json::objectValue; for (string const& contractName: m_compilerStack.contractNames()) { + size_t colon = contractName.find(':'); + solAssert(colon != string::npos, ""); + string file = contractName.substr(0, colon); + string name = contractName.substr(colon + 1); + // ABI, documentation and metadata Json::Value contractData(Json::objectValue); contractData["abi"] = dev::jsonCompactPrint(m_compilerStack.metadata(contractName, DocumentationType::ABIInterface)); @@ -317,10 +322,12 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) contractData["evm"] = evmData; - contractsOutput[contractName] = contractData; + if (!contractsOutput.isMember(file)) + contractsOutput[file] = Json::objectValue; + + contractsOutput[file][name] = contractData; } - output["contracts"] = Json::objectValue; - output["contracts"][""] = contractsOutput; + output["contracts"] = contractsOutput; return output; } -- cgit v1.2.3 From df7e703925e712a91871c517733c5d7949457ee2 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 30 Mar 2017 02:41:38 +0100 Subject: Support the metadata.useLiteralContent setting --- libsolidity/interface/StandardCompiler.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 13f82f60..42404a1c 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -166,6 +166,9 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) libraries[library] = h160(jsonSourceName[library].asString()); } + Json::Value metadataSettings = settings.get("metadata", Json::Value()); + m_compilerStack.useMetadataLiteralSources(metadataSettings.get("useLiteralContent", Json::Value(false)).asBool()); + auto scannerFromSourceName = [&](string const& _sourceName) -> solidity::Scanner const& { return m_compilerStack.scanner(_sourceName); }; Json::Value errors = Json::arrayValue; -- cgit v1.2.3 From 77d5148f0d79c57d5d1ad3951f3692c9098cf194 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 30 Mar 2017 03:17:17 +0100 Subject: Reject import URLs for now --- libsolidity/interface/StandardCompiler.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 42404a1c..4bc8f8e1 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -143,7 +143,12 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) return formatFatalError("JSONError", "No input sources specified."); for (auto const& sourceName: sources.getMemberNames()) - m_compilerStack.addSource(sourceName, sources[sourceName]["content"].asString()); + if (sources[sourceName]["content"].isString()) + m_compilerStack.addSource(sourceName, sources[sourceName]["content"].asString()); + else if (sources[sourceName]["urls"].isArray()) + return formatFatalError("UnimplementedFeatureError", "Input URLs not supported yet."); + else + return formatFatalError("JSONError", "Invalid input source specified."); Json::Value const& settings = _input.get("settings", Json::Value()); -- cgit v1.2.3 From b513db74a0bd8d5f3730cb3fec9f5385f5f194f8 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 10 Apr 2017 20:29:57 +0100 Subject: Support gas estimates in StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 4bc8f8e1..8fffea8e 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -308,7 +308,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) evmData["assembly"] = tmp.str(); evmData["legacyAssembly"] = m_compilerStack.streamAssembly(tmp, contractName, createSourceList(_input), true); evmData["methodIdentifiers"] = methodIdentifiers(m_compilerStack.contractDefinition(contractName)); - // @TODO: add gasEstimates + evmData["gasEstimates"] = m_compilerStack.gasEstimates(contractName); // EVM bytecode Json::Value bytecode(Json::objectValue); -- cgit v1.2.3 From aa0776d5e806be8f10ebcc21210ed25290c33598 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 11 Apr 2017 09:43:30 +0100 Subject: Support Why3 in StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 8fffea8e..a2909fa3 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -337,6 +337,30 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) } output["contracts"] = contractsOutput; + { + ErrorList formalErrors; + if (m_compilerStack.prepareFormalAnalysis(&formalErrors)) + output["why3"] = m_compilerStack.formalTranslation(); + + for (auto const& error: formalErrors) + { + auto err = dynamic_pointer_cast(error); + + errors.append(formatErrorWithException( + *error, + err->type() == Error::Type::Warning, + err->typeName(), + "general", + "", + scannerFromSourceName + )); + } + + // FIXME!! + if (!formalErrors.empty()) + output["errors"] = errors; + } + return output; } -- cgit v1.2.3 From 413c146eddb744f6b5d8dc248f63f4d46449306b Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 19 Apr 2017 14:11:31 +0100 Subject: Enclose local functions in a namespace --- libsolidity/interface/StandardCompiler.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index a2909fa3..6cfe6f3a 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -30,6 +30,8 @@ using namespace std; using namespace dev; using namespace dev::solidity; +namespace { + Json::Value formatError( bool _warning, string const& _type, @@ -134,6 +136,8 @@ Json::Value formatLinkReferences(std::map const& linkRefere return ret; } +} + Json::Value StandardCompiler::compileInternal(Json::Value const& _input) { m_compilerStack.reset(false); -- cgit v1.2.3 From 6d132602326e9a981141d9e5213ba65c423dd099 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 19 Apr 2017 15:52:54 +0100 Subject: Pull out collectEVMObject --- libsolidity/interface/StandardCompiler.cpp | 36 ++++++++++++++++-------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 6cfe6f3a..bd2e64c6 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -136,6 +136,16 @@ Json::Value formatLinkReferences(std::map const& linkRefere return ret; } +Json::Value collectEVMObject(eth::LinkerObject const& _object, string const* _sourceMap) +{ + Json::Value output = Json::objectValue; + output["object"] = _object.toHex(); + output["opcodes"] = solidity::disassemble(_object.bytecode); + output["sourceMap"] = _sourceMap ? *_sourceMap : ""; + output["linkReferences"] = formatLinkReferences(_object.linkReferences); + return output; +} + } Json::Value StandardCompiler::compileInternal(Json::Value const& _input) @@ -314,23 +324,15 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) evmData["methodIdentifiers"] = methodIdentifiers(m_compilerStack.contractDefinition(contractName)); evmData["gasEstimates"] = m_compilerStack.gasEstimates(contractName); - // EVM bytecode - Json::Value bytecode(Json::objectValue); - bytecode["object"] = m_compilerStack.object(contractName).toHex(); - bytecode["opcodes"] = solidity::disassemble(m_compilerStack.object(contractName).bytecode); - auto sourceMap = m_compilerStack.sourceMapping(contractName); - bytecode["sourceMap"] = sourceMap ? *sourceMap : ""; - bytecode["linkReferences"] = formatLinkReferences(m_compilerStack.object(contractName).linkReferences); - evmData["bytecode"] = bytecode; - - // EVM deployed bytecode - Json::Value deployedBytecode(Json::objectValue); - deployedBytecode["object"] = m_compilerStack.runtimeObject(contractName).toHex(); - deployedBytecode["opcodes"] = solidity::disassemble(m_compilerStack.runtimeObject(contractName).bytecode); - auto runtimeSourceMap = m_compilerStack.runtimeSourceMapping(contractName); - deployedBytecode["sourceMap"] = runtimeSourceMap ? *runtimeSourceMap : ""; - deployedBytecode["linkReferences"] = formatLinkReferences(m_compilerStack.runtimeObject(contractName).linkReferences); - evmData["deployedBytecode"] = deployedBytecode; + evmData["bytecode"] = collectEVMObject( + m_compilerStack.object(contractName), + m_compilerStack.sourceMapping(contractName) + ); + + evmData["deployedBytecode"] = collectEVMObject( + m_compilerStack.runtimeObject(contractName), + m_compilerStack.runtimeSourceMapping(contractName) + ); contractData["evm"] = evmData; -- cgit v1.2.3 From f71b465eb7575ae7639fbd03b550208c8f31ce43 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 19 Apr 2017 15:53:11 +0100 Subject: Ensure the language field is present in the JSON --- libsolidity/interface/StandardCompiler.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index bd2e64c6..3cff319f 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -152,6 +152,12 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) { m_compilerStack.reset(false); + if (!_input.isObject()) + return formatFatalError("JSONError", "Input is not a JSON object."); + + if (_input["language"] != "Solidity") + return formatFatalError("JSONError", "Only \"Solidity\" is supported as a language."); + Json::Value const& sources = _input["sources"]; if (!sources) return formatFatalError("JSONError", "No input sources specified."); -- cgit v1.2.3 From 6ae7a87b789d9ed60360ab9b7fa6593f9ab3b5ff Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 19 Apr 2017 18:53:39 +0100 Subject: Rename ast to legacyAST in StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 3cff319f..db89e16c 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -301,7 +301,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) { Json::Value sourceResult = Json::objectValue; sourceResult["id"] = sourceIndex++; - sourceResult["ast"] = ASTJsonConverter(m_compilerStack.ast(source), m_compilerStack.sourceIndices()).json(); + sourceResult["legacyAST"] = ASTJsonConverter(m_compilerStack.ast(source), m_compilerStack.sourceIndices()).json(); output["sources"][source] = sourceResult; } -- cgit v1.2.3 From 8de02c777856daffc2d48cc68a15b6b6f16ce134 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 19 Apr 2017 16:45:36 +0100 Subject: Support URL sources in StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 35 ++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index db89e16c..4a8787b3 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -162,11 +162,43 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) if (!sources) return formatFatalError("JSONError", "No input sources specified."); + Json::Value errors = Json::arrayValue; + for (auto const& sourceName: sources.getMemberNames()) if (sources[sourceName]["content"].isString()) m_compilerStack.addSource(sourceName, sources[sourceName]["content"].asString()); else if (sources[sourceName]["urls"].isArray()) - return formatFatalError("UnimplementedFeatureError", "Input URLs not supported yet."); + { + if (!m_readFile) + return formatFatalError("JSONError", "No import callback supplied, but URL is requested."); + + bool found = false; + vector failures; + + for (auto const& url: sources[sourceName]["urls"]) + { + ReadFile::Result result = m_readFile(url.asString()); + if (result.success) + { + m_compilerStack.addSource(sourceName, result.contentsOrErrorMessage); + found = true; + break; + } + else + failures.push_back("Cannot import url (\"" + url.asString() + "\"): " + result.contentsOrErrorMessage); + } + + for (auto const& failure: failures) + { + /// If the import succeeded, let mark all the others as warnings, otherwise all of them are errors. + errors.append(formatError( + found ? true : false, + "IOError", + "general", + failure + )); + } + } else return formatFatalError("JSONError", "Invalid input source specified."); @@ -196,7 +228,6 @@ 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 -- cgit v1.2.3 From e24c35bce04225f5301a65108889f9487bf5d7c5 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sun, 23 Apr 2017 19:43:06 +0100 Subject: Be a bit more verbose and capture Boost exceptions in StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 4a8787b3..5408db2e 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -413,9 +413,13 @@ Json::Value StandardCompiler::compile(Json::Value const& _input) { return compileInternal(_input); } + catch (Exception const& _exception) + { + return formatFatalError("InternalCompilerError", "Internal exception in StandardCompiler::compileInternal: " + boost::diagnostic_information(_exception)); + } catch (...) { - return formatFatalError("InternalCompilerError", "Internal exception in StandardCompiler::compilerInternal"); + return formatFatalError("InternalCompilerError", "Internal exception in StandardCompiler::compileInternal"); } } -- cgit v1.2.3 From 43eb8398711f7fafd703cff06092f3dfd2b0e748 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 24 Apr 2017 11:44:33 +0100 Subject: Do not fail if parsing failed in StandardCompiler --- libsolidity/interface/StandardCompiler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 5408db2e..6a8417de 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -337,7 +337,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) } Json::Value contractsOutput = Json::objectValue; - for (string const& contractName: m_compilerStack.contractNames()) + for (string const& contractName: success ? m_compilerStack.contractNames() : vector()) { size_t colon = contractName.find(':'); solAssert(colon != string::npos, ""); -- cgit v1.2.3 From 4a9ba5b9528a704392dca52c6b146d3baa0cce7d Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Sat, 22 Apr 2017 14:43:10 +0100 Subject: Verify supplied hash in JSON I/O --- libsolidity/interface/StandardCompiler.cpp | 49 +++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 4a8787b3..582765e7 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -25,6 +25,7 @@ #include #include #include +#include using namespace std; using namespace dev; @@ -91,6 +92,19 @@ Json::Value formatErrorWithException( return formatError(_warning, _type, _component, message, formattedMessage, location); } +/// Returns true iff @a _hash (hex with 0x prefix) is the Keccak256 hash of the binary data in @a _content. +bool hashMatchesContent(string const& _hash, string const& _content) +{ + try + { + return dev::h256(_hash) == dev::keccak256(_content); + } + catch (dev::BadHexCharacter) + { + return false; + } +} + StringMap createSourceList(Json::Value const& _input) { StringMap sources; @@ -165,8 +179,24 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) Json::Value errors = Json::arrayValue; for (auto const& sourceName: sources.getMemberNames()) + { + string hash; + if (sources[sourceName]["keccak256"].isString()) + hash = sources[sourceName]["keccak256"].asString(); + if (sources[sourceName]["content"].isString()) - m_compilerStack.addSource(sourceName, sources[sourceName]["content"].asString()); + { + string content = sources[sourceName]["content"].asString(); + if (!hash.empty() && !hashMatchesContent(hash, content)) + errors.append(formatError( + false, + "IOError", + "general", + "Mismatch between content and supplied hash for \"" + sourceName + "\"" + )); + else + m_compilerStack.addSource(sourceName, content); + } else if (sources[sourceName]["urls"].isArray()) { if (!m_readFile) @@ -180,9 +210,19 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) ReadFile::Result result = m_readFile(url.asString()); if (result.success) { - m_compilerStack.addSource(sourceName, result.contentsOrErrorMessage); - found = true; - break; + if (!hash.empty() && !hashMatchesContent(hash, result.contentsOrErrorMessage)) + errors.append(formatError( + false, + "IOError", + "general", + "Mismatch between content and supplied hash for \"" + sourceName + "\" at \"" + url.asString() + "\"" + )); + else + { + m_compilerStack.addSource(sourceName, result.contentsOrErrorMessage); + found = true; + break; + } } else failures.push_back("Cannot import url (\"" + url.asString() + "\"): " + result.contentsOrErrorMessage); @@ -201,6 +241,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) } else return formatFatalError("JSONError", "Invalid input source specified."); + } Json::Value const& settings = _input.get("settings", Json::Value()); -- cgit v1.2.3 From 2f66c69bd107928ede7b52d1404fdf7e94c84a28 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 24 Apr 2017 22:38:03 +0100 Subject: Do not crash on invalid JSON input --- libsolidity/interface/StandardCompiler.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 2b280dd5..a1e6deb0 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -181,6 +181,10 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) for (auto const& sourceName: sources.getMemberNames()) { string hash; + + if (!sources[sourceName].isObject()) + return formatFatalError("JSONError", "Source input is not a JSON object."); + if (sources[sourceName]["keccak256"].isString()) hash = sources[sourceName]["keccak256"].asString(); -- cgit v1.2.3 From 5e7a643051b67c43eaaab69dce6c99a503a44820 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 24 Apr 2017 22:49:50 +0100 Subject: Catch jsoncpp exceptions --- libsolidity/interface/StandardCompiler.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index a1e6deb0..2b5e861b 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -458,6 +458,14 @@ Json::Value StandardCompiler::compile(Json::Value const& _input) { return compileInternal(_input); } + catch (Json::LogicError const& _exception) + { + return formatFatalError("InternalCompilerError", string("JSON logic exception: ") + _exception.what()); + } + catch (Json::RuntimeError const& _exception) + { + return formatFatalError("InternalCompilerError", string("JSON runtime exception: ") + _exception.what()); + } catch (Exception const& _exception) { return formatFatalError("InternalCompilerError", "Internal exception in StandardCompiler::compileInternal: " + boost::diagnostic_information(_exception)); -- cgit v1.2.3 From 2871663cadca8355764c64bc921b2fc6126efb2c Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 2 May 2017 14:49:13 +0100 Subject: Remove why3 from standard compiler --- libsolidity/interface/StandardCompiler.cpp | 24 ------------------------ 1 file changed, 24 deletions(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 2b5e861b..db0cbd16 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -425,30 +425,6 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) } output["contracts"] = contractsOutput; - { - ErrorList formalErrors; - if (m_compilerStack.prepareFormalAnalysis(&formalErrors)) - output["why3"] = m_compilerStack.formalTranslation(); - - for (auto const& error: formalErrors) - { - auto err = dynamic_pointer_cast(error); - - errors.append(formatErrorWithException( - *error, - err->type() == Error::Type::Warning, - err->typeName(), - "general", - "", - scannerFromSourceName - )); - } - - // FIXME!! - if (!formalErrors.empty()) - output["errors"] = errors; - } - return output; } -- cgit v1.2.3 From ed3ab3506a8acb83bda9477f733d2cb07125a74a Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 2 May 2017 15:20:27 +0100 Subject: Follow the JSON I/O spec closely --- libsolidity/interface/StandardCompiler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'libsolidity/interface/StandardCompiler.cpp') diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 2b5e861b..8670234b 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -391,10 +391,10 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) // ABI, documentation and metadata Json::Value contractData(Json::objectValue); - contractData["abi"] = dev::jsonCompactPrint(m_compilerStack.metadata(contractName, DocumentationType::ABIInterface)); + contractData["abi"] = m_compilerStack.metadata(contractName, DocumentationType::ABIInterface); contractData["metadata"] = m_compilerStack.onChainMetadata(contractName); - contractData["userdoc"] = dev::jsonCompactPrint(m_compilerStack.metadata(contractName, DocumentationType::NatspecUser)); - contractData["devdoc"] = dev::jsonCompactPrint(m_compilerStack.metadata(contractName, DocumentationType::NatspecDev)); + contractData["userdoc"] = m_compilerStack.metadata(contractName, DocumentationType::NatspecUser); + contractData["devdoc"] = m_compilerStack.metadata(contractName, DocumentationType::NatspecDev); // EVM Json::Value evmData(Json::objectValue); -- cgit v1.2.3