aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity
diff options
context:
space:
mode:
authorAlex Beregszaszi <alex@rtfs.hu>2017-11-30 05:09:03 +0800
committerGitHub <noreply@github.com>2017-11-30 05:09:03 +0800
commitffb3a3c06c4d436aaf03efccf31301b472cd8137 (patch)
tree9fd60dbbca353908826b79cb49320940d89cc8d8 /libsolidity
parent07591478dd78dee56c5b83a62a314e984c3a83a6 (diff)
parent3576ccf5b36f41d36898919eee7316b9c7c49d41 (diff)
downloaddexon-solidity-ffb3a3c06c4d436aaf03efccf31301b472cd8137.tar.gz
dexon-solidity-ffb3a3c06c4d436aaf03efccf31301b472cd8137.tar.zst
dexon-solidity-ffb3a3c06c4d436aaf03efccf31301b472cd8137.zip
Merge pull request #2146 from ethereum/jsonio-target-selection
Support target artifact selection in JSON I/O
Diffstat (limited to 'libsolidity')
-rw-r--r--libsolidity/interface/StandardCompiler.cpp117
1 files changed, 97 insertions, 20 deletions
diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp
index 430739ac..ad01821e 100644
--- a/libsolidity/interface/StandardCompiler.cpp
+++ b/libsolidity/interface/StandardCompiler.cpp
@@ -131,6 +131,61 @@ StringMap createSourceList(Json::Value const& _input)
return sources;
}
+bool isArtifactRequested(Json::Value const& _outputSelection, string const& _artifact)
+{
+ for (auto const& artifact: _outputSelection)
+ /// @TODO support sub-matching, e.g "evm" matches "evm.assembly"
+ if (artifact == "*" || artifact == _artifact)
+ return true;
+ return false;
+}
+
+///
+/// @a _outputSelection is a JSON object containining a two-level hashmap, where the first level is the filename,
+/// the second level is the contract name and the value is an array of artifact names to be requested for that contract.
+/// @a _file is the current file
+/// @a _contract is the current contract
+/// @a _artifact is the current artifact name
+///
+/// @returns true if the @a _outputSelection has a match for the requested target in the specific file / contract.
+///
+/// In @a _outputSelection the use of '*' as a wildcard is permitted.
+///
+/// @TODO optimise this. Perhaps flatten the structure upfront.
+///
+bool isArtifactRequested(Json::Value const& _outputSelection, string const& _file, string const& _contract, string const& _artifact)
+{
+ if (!_outputSelection.isObject())
+ return false;
+
+ for (auto const& file: { _file, string("*") })
+ if (_outputSelection.isMember(file) && _outputSelection[file].isObject())
+ {
+ /// For SourceUnit-level targets (such as AST) only allow empty name, otherwise
+ /// for Contract-level targets try both contract name and wildcard
+ vector<string> contracts{ _contract };
+ if (!_contract.empty())
+ contracts.push_back("*");
+ for (auto const& contract: contracts)
+ if (
+ _outputSelection[file].isMember(contract) &&
+ _outputSelection[file][contract].isArray() &&
+ isArtifactRequested(_outputSelection[file][contract], _artifact)
+ )
+ return true;
+ }
+
+ return false;
+}
+
+bool isArtifactRequested(Json::Value const& _outputSelection, string const& _file, string const& _contract, vector<string> const& _artifacts)
+{
+ for (auto const& artifact: _artifacts)
+ if (isArtifactRequested(_outputSelection, _file, _contract, artifact))
+ return true;
+ return false;
+}
+
Json::Value formatLinkReferences(std::map<size_t, std::string> const& linkReferences)
{
Json::Value ret(Json::objectValue);
@@ -396,8 +451,10 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
{
Json::Value sourceResult = Json::objectValue;
sourceResult["id"] = sourceIndex++;
- sourceResult["ast"] = ASTJsonConverter(false, m_compilerStack.sourceIndices()).toJson(m_compilerStack.ast(sourceName));
- sourceResult["legacyAST"] = ASTJsonConverter(true, m_compilerStack.sourceIndices()).toJson(m_compilerStack.ast(sourceName));
+ if (isArtifactRequested(outputSelection, sourceName, "", "ast"))
+ sourceResult["ast"] = ASTJsonConverter(false, m_compilerStack.sourceIndices()).toJson(m_compilerStack.ast(sourceName));
+ if (isArtifactRequested(outputSelection, sourceName, "", "legacyAST"))
+ sourceResult["legacyAST"] = ASTJsonConverter(true, m_compilerStack.sourceIndices()).toJson(m_compilerStack.ast(sourceName));
output["sources"][sourceName] = sourceResult;
}
@@ -411,28 +468,48 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
// ABI, documentation and metadata
Json::Value contractData(Json::objectValue);
- contractData["abi"] = m_compilerStack.contractABI(contractName);
- contractData["metadata"] = m_compilerStack.metadata(contractName);
- contractData["userdoc"] = m_compilerStack.natspecUser(contractName);
- contractData["devdoc"] = m_compilerStack.natspecDev(contractName);
+ if (isArtifactRequested(outputSelection, file, name, "abi"))
+ contractData["abi"] = m_compilerStack.contractABI(contractName);
+ if (isArtifactRequested(outputSelection, file, name, "metadata"))
+ contractData["metadata"] = m_compilerStack.metadata(contractName);
+ if (isArtifactRequested(outputSelection, file, name, "userdoc"))
+ contractData["userdoc"] = m_compilerStack.natspecUser(contractName);
+ if (isArtifactRequested(outputSelection, file, name, "devdoc"))
+ contractData["devdoc"] = m_compilerStack.natspecDev(contractName);
// EVM
Json::Value evmData(Json::objectValue);
// @TODO: add ir
- evmData["assembly"] = m_compilerStack.assemblyString(contractName, createSourceList(_input));
- evmData["legacyAssembly"] = m_compilerStack.assemblyJSON(contractName, createSourceList(_input));
- evmData["methodIdentifiers"] = m_compilerStack.methodIdentifiers(contractName);
- evmData["gasEstimates"] = m_compilerStack.gasEstimates(contractName);
-
- evmData["bytecode"] = collectEVMObject(
- m_compilerStack.object(contractName),
- m_compilerStack.sourceMapping(contractName)
- );
-
- evmData["deployedBytecode"] = collectEVMObject(
- m_compilerStack.runtimeObject(contractName),
- m_compilerStack.runtimeSourceMapping(contractName)
- );
+ if (isArtifactRequested(outputSelection, file, name, "evm.assembly"))
+ evmData["assembly"] = m_compilerStack.assemblyString(contractName, createSourceList(_input));
+ if (isArtifactRequested(outputSelection, file, name, "evm.legacyAssembly"))
+ evmData["legacyAssembly"] = m_compilerStack.assemblyJSON(contractName, createSourceList(_input));
+ if (isArtifactRequested(outputSelection, file, name, "evm.methodIdentifiers"))
+ evmData["methodIdentifiers"] = m_compilerStack.methodIdentifiers(contractName);
+ if (isArtifactRequested(outputSelection, file, name, "evm.gasEstimates"))
+ evmData["gasEstimates"] = m_compilerStack.gasEstimates(contractName);
+
+ if (isArtifactRequested(
+ outputSelection,
+ file,
+ name,
+ { "evm.bytecode", "evm.bytecode.object", "evm.bytecode.opcodes", "evm.bytecode.sourceMap", "evm.bytecode.linkReferences" }
+ ))
+ evmData["bytecode"] = collectEVMObject(
+ m_compilerStack.object(contractName),
+ m_compilerStack.sourceMapping(contractName)
+ );
+
+ if (isArtifactRequested(
+ outputSelection,
+ file,
+ name,
+ { "evm.deployedBytecode", "evm.deployedBytecode.object", "evm.deployedBytecode.opcodes", "evm.deployedBytecode.sourceMap", "evm.deployedBytecode.linkReferences" }
+ ))
+ evmData["deployedBytecode"] = collectEVMObject(
+ m_compilerStack.runtimeObject(contractName),
+ m_compilerStack.runtimeSourceMapping(contractName)
+ );
contractData["evm"] = evmData;