CommandLineParser: componentMap() for CompilerOutputs

This commit is contained in:
Kamil Śliwak 2021-09-30 15:51:24 +02:00
parent 1247239fe8
commit 809321e88d
2 changed files with 63 additions and 66 deletions

View File

@ -56,10 +56,8 @@ static string const g_strAllowPaths = "allow-paths";
static string const g_strBasePath = "base-path"; static string const g_strBasePath = "base-path";
static string const g_strIncludePath = "include-path"; static string const g_strIncludePath = "include-path";
static string const g_strAsm = "asm"; static string const g_strAsm = "asm";
static string const g_strAsmJson = "asm-json";
static string const g_strAssemble = "assemble"; static string const g_strAssemble = "assemble";
static string const g_strAst = "ast"; static string const g_strAst = "ast";
static string const g_strAstCompactJson = "ast-compact-json";
static string const g_strBinary = "bin"; static string const g_strBinary = "bin";
static string const g_strBinaryRuntime = "bin-runtime"; static string const g_strBinaryRuntime = "bin-runtime";
static string const g_strCombinedJson = "combined-json"; static string const g_strCombinedJson = "combined-json";
@ -76,8 +74,6 @@ static string const g_strImportAst = "import-ast";
static string const g_strInputFile = "input-file"; static string const g_strInputFile = "input-file";
static string const g_strYul = "yul"; static string const g_strYul = "yul";
static string const g_strYulDialect = "yul-dialect"; static string const g_strYulDialect = "yul-dialect";
static string const g_strIR = "ir";
static string const g_strIROptimized = "ir-optimized";
static string const g_strIPFS = "ipfs"; static string const g_strIPFS = "ipfs";
static string const g_strLicense = "license"; static string const g_strLicense = "license";
static string const g_strLibraries = "libraries"; static string const g_strLibraries = "libraries";
@ -213,27 +209,22 @@ bool CommandLineParser::checkMutuallyExclusive(vector<string> const& _optionName
bool CompilerOutputs::operator==(CompilerOutputs const& _other) const noexcept bool CompilerOutputs::operator==(CompilerOutputs const& _other) const noexcept
{ {
static_assert( for (bool CompilerOutputs::* member: componentMap() | ranges::views::values)
sizeof(*this) == 15 * sizeof(bool), if (this->*member != _other.*member)
"Remember to update code below if you add/remove fields." return false;
); return true;
}
return string const& CompilerOutputs::componentName(bool CompilerOutputs::* _component)
astCompactJson == _other.astCompactJson && {
asm_ == _other.asm_ && solAssert(_component, "");
asmJson == _other.asmJson &&
opcodes == _other.opcodes && // NOTE: Linear search is not optimal but it's simpler than getting pointers-to-members to work as map keys.
binary == _other.binary && for (auto const& [componentName, component]: CompilerOutputs::componentMap())
binaryRuntime == _other.binaryRuntime && if (component == _component)
abi == _other.abi && return componentName;
ir == _other.ir &&
irOptimized == _other.irOptimized && solAssert(false, "");
ewasm == _other.ewasm &&
signatureHashes == _other.signatureHashes &&
natspecUser == _other.natspecUser &&
natspecDev == _other.natspecDev &&
metadata == _other.metadata &&
storageLayout == _other.storageLayout;
} }
bool CombinedJsonRequests::operator==(CombinedJsonRequests const& _other) const noexcept bool CombinedJsonRequests::operator==(CombinedJsonRequests const& _other) const noexcept
@ -511,7 +502,7 @@ at standard output or in files in the output directory, if specified.
Imports are automatically read from the filesystem, but it is also possible to Imports are automatically read from the filesystem, but it is also possible to
remap paths using the context:prefix=path syntax. remap paths using the context:prefix=path syntax.
Example: Example:
solc --)" + g_strBinary + R"( -o /tmp/solcoutput dapp-bin=/usr/local/lib/dapp-bin contract.sol solc --)" + CompilerOutputs::componentName(&CompilerOutputs::binary) + R"( -o /tmp/solcoutput dapp-bin=/usr/local/lib/dapp-bin contract.sol
General Information)").c_str(), General Information)").c_str(),
po::options_description::m_default_line_length, po::options_description::m_default_line_length,
@ -683,21 +674,21 @@ General Information)").c_str(),
po::options_description outputComponents("Output Components"); po::options_description outputComponents("Output Components");
outputComponents.add_options() outputComponents.add_options()
(g_strAstCompactJson.c_str(), "AST of all source files in a compact JSON format.") (CompilerOutputs::componentName(&CompilerOutputs::astCompactJson).c_str(), "AST of all source files in a compact JSON format.")
(g_strAsm.c_str(), "EVM assembly of the contracts.") (CompilerOutputs::componentName(&CompilerOutputs::asm_).c_str(), "EVM assembly of the contracts.")
(g_strAsmJson.c_str(), "EVM assembly of the contracts in JSON format.") (CompilerOutputs::componentName(&CompilerOutputs::asmJson).c_str(), "EVM assembly of the contracts in JSON format.")
(g_strOpcodes.c_str(), "Opcodes of the contracts.") (CompilerOutputs::componentName(&CompilerOutputs::opcodes).c_str(), "Opcodes of the contracts.")
(g_strBinary.c_str(), "Binary of the contracts in hex.") (CompilerOutputs::componentName(&CompilerOutputs::binary).c_str(), "Binary of the contracts in hex.")
(g_strBinaryRuntime.c_str(), "Binary of the runtime part of the contracts in hex.") (CompilerOutputs::componentName(&CompilerOutputs::binaryRuntime).c_str(), "Binary of the runtime part of the contracts in hex.")
(g_strAbi.c_str(), "ABI specification of the contracts.") (CompilerOutputs::componentName(&CompilerOutputs::abi).c_str(), "ABI specification of the contracts.")
(g_strIR.c_str(), "Intermediate Representation (IR) of all contracts (EXPERIMENTAL).") (CompilerOutputs::componentName(&CompilerOutputs::ir).c_str(), "Intermediate Representation (IR) of all contracts (EXPERIMENTAL).")
(g_strIROptimized.c_str(), "Optimized intermediate Representation (IR) of all contracts (EXPERIMENTAL).") (CompilerOutputs::componentName(&CompilerOutputs::irOptimized).c_str(), "Optimized intermediate Representation (IR) of all contracts (EXPERIMENTAL).")
(g_strEwasm.c_str(), "Ewasm text representation of all contracts (EXPERIMENTAL).") (CompilerOutputs::componentName(&CompilerOutputs::ewasm).c_str(), "Ewasm text representation of all contracts (EXPERIMENTAL).")
(g_strSignatureHashes.c_str(), "Function signature hashes of the contracts.") (CompilerOutputs::componentName(&CompilerOutputs::signatureHashes).c_str(), "Function signature hashes of the contracts.")
(g_strNatspecUser.c_str(), "Natspec user documentation of all contracts.") (CompilerOutputs::componentName(&CompilerOutputs::natspecUser).c_str(), "Natspec user documentation of all contracts.")
(g_strNatspecDev.c_str(), "Natspec developer documentation of all contracts.") (CompilerOutputs::componentName(&CompilerOutputs::natspecDev).c_str(), "Natspec developer documentation of all contracts.")
(g_strMetadata.c_str(), "Combined Metadata JSON whose Swarm hash is stored on-chain.") (CompilerOutputs::componentName(&CompilerOutputs::metadata).c_str(), "Combined Metadata JSON whose Swarm hash is stored on-chain.")
(g_strStorageLayout.c_str(), "Slots, offsets and types of the contract's state variables.") (CompilerOutputs::componentName(&CompilerOutputs::storageLayout).c_str(), "Slots, offsets and types of the contract's state variables.")
; ;
desc.add(outputComponents); desc.add(outputComponents);
@ -889,14 +880,14 @@ bool CommandLineParser::processArgs()
return false; return false;
array<string, 8> const conflictingWithStopAfter{ array<string, 8> const conflictingWithStopAfter{
g_strBinary, CompilerOutputs::componentName(&CompilerOutputs::binary),
g_strIR, CompilerOutputs::componentName(&CompilerOutputs::ir),
g_strIROptimized, CompilerOutputs::componentName(&CompilerOutputs::irOptimized),
g_strEwasm, CompilerOutputs::componentName(&CompilerOutputs::ewasm),
g_strGas, g_strGas,
g_strAsm, CompilerOutputs::componentName(&CompilerOutputs::asm_),
g_strAsmJson, CompilerOutputs::componentName(&CompilerOutputs::asmJson),
g_strOpcodes CompilerOutputs::componentName(&CompilerOutputs::opcodes),
}; };
for (auto& option: conflictingWithStopAfter) for (auto& option: conflictingWithStopAfter)
@ -965,25 +956,8 @@ bool CommandLineParser::processArgs()
m_options.formatting.json.indent = m_args[g_strJsonIndent].as<uint32_t>(); m_options.formatting.json.indent = m_args[g_strJsonIndent].as<uint32_t>();
} }
static_assert( for (auto&& [optionName, outputComponent]: CompilerOutputs::componentMap())
sizeof(m_options.compiler.outputs) == 15 * sizeof(bool), m_options.compiler.outputs.*outputComponent = (m_args.count(optionName) > 0);
"Remember to update code below if you add/remove fields."
);
m_options.compiler.outputs.astCompactJson = (m_args.count(g_strAstCompactJson) > 0);
m_options.compiler.outputs.asm_ = (m_args.count(g_strAsm) > 0);
m_options.compiler.outputs.asmJson = (m_args.count(g_strAsmJson) > 0);
m_options.compiler.outputs.opcodes = (m_args.count(g_strOpcodes) > 0);
m_options.compiler.outputs.binary = (m_args.count(g_strBinary) > 0);
m_options.compiler.outputs.binaryRuntime = (m_args.count(g_strBinaryRuntime) > 0);
m_options.compiler.outputs.abi = (m_args.count(g_strAbi) > 0);
m_options.compiler.outputs.ir = (m_args.count(g_strIR) > 0);
m_options.compiler.outputs.irOptimized = (m_args.count(g_strIROptimized) > 0);
m_options.compiler.outputs.ewasm = (m_args.count(g_strEwasm) > 0);
m_options.compiler.outputs.signatureHashes = (m_args.count(g_strSignatureHashes) > 0);
m_options.compiler.outputs.natspecUser = (m_args.count(g_strNatspecUser) > 0);
m_options.compiler.outputs.natspecDev = (m_args.count(g_strNatspecDev) > 0);
m_options.compiler.outputs.metadata = (m_args.count(g_strMetadata) > 0);
m_options.compiler.outputs.storageLayout = (m_args.count(g_strStorageLayout) > 0);
m_options.compiler.estimateGas = (m_args.count(g_strGas) > 0); m_options.compiler.estimateGas = (m_args.count(g_strGas) > 0);

View File

@ -56,6 +56,29 @@ struct CompilerOutputs
bool operator!=(CompilerOutputs const& _other) const noexcept { return !(*this == _other); } bool operator!=(CompilerOutputs const& _other) const noexcept { return !(*this == _other); }
bool operator==(CompilerOutputs const& _other) const noexcept; bool operator==(CompilerOutputs const& _other) const noexcept;
static std::string const& componentName(bool CompilerOutputs::* _component);
static auto const& componentMap()
{
static std::map<std::string, bool CompilerOutputs::*> const components = {
{"ast-compact-json", &CompilerOutputs::astCompactJson},
{"asm", &CompilerOutputs::asm_},
{"asm-json", &CompilerOutputs::asmJson},
{"opcodes", &CompilerOutputs::opcodes},
{"bin", &CompilerOutputs::binary},
{"bin-runtime", &CompilerOutputs::binaryRuntime},
{"abi", &CompilerOutputs::abi},
{"ir", &CompilerOutputs::ir},
{"ir-optimized", &CompilerOutputs::irOptimized},
{"ewasm", &CompilerOutputs::ewasm},
{"hashes", &CompilerOutputs::signatureHashes},
{"userdoc", &CompilerOutputs::natspecUser},
{"devdoc", &CompilerOutputs::natspecDev},
{"metadata", &CompilerOutputs::metadata},
{"storage-layout", &CompilerOutputs::storageLayout},
};
return components;
}
bool astCompactJson = false; bool astCompactJson = false;
bool asm_ = false; bool asm_ = false;
bool asmJson = false; bool asmJson = false;