Dropping --opcodes support

This commit is contained in:
Paul 2023-09-11 11:55:30 +00:00
parent 16ae76cad7
commit 8e3e63d35a
6 changed files with 93 additions and 123 deletions

View File

@ -130,7 +130,6 @@ static std::string const g_strGeneratedSources = "generated-sources";
static std::string const g_strGeneratedSourcesRuntime = "generated-sources-runtime";
static std::string const g_strNatspecDev = "devdoc";
static std::string const g_strNatspecUser = "userdoc";
static std::string const g_strOpcodes = "opcodes";
static std::string const g_strSignatureHashes = "hashes";
static std::string const g_strSourceList = "sourceList";
static std::string const g_strSources = "sources";
@ -154,7 +153,6 @@ static bool needsHumanTargetedStdout(CommandLineOptions const& _options)
_options.compiler.outputs.metadata ||
_options.compiler.outputs.natspecUser ||
_options.compiler.outputs.natspecDev ||
_options.compiler.outputs.opcodes ||
_options.compiler.outputs.signatureHashes ||
_options.compiler.outputs.storageLayout;
}
@ -192,20 +190,6 @@ void CommandLineInterface::handleBinary(std::string const& _contract)
}
}
void CommandLineInterface::handleOpcode(std::string const& _contract)
{
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
if (!m_options.output.dir.empty())
createFile(m_compiler->filesystemFriendlyName(_contract) + ".opcode", evmasm::disassemble(m_compiler->object(_contract).bytecode, m_options.output.evmVersion));
else
{
sout() << "Opcodes:" << std::endl;
sout() << std::uppercase << evmasm::disassemble(m_compiler->object(_contract).bytecode, m_options.output.evmVersion);
sout() << std::endl;
}
}
void CommandLineInterface::handleIR(std::string const& _contractName)
{
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
@ -295,8 +279,6 @@ void CommandLineInterface::handleBytecode(std::string const& _contract)
{
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
if (m_options.compiler.outputs.opcodes)
handleOpcode(_contract);
if (m_options.compiler.outputs.binary || m_options.compiler.outputs.binaryRuntime)
handleBinary(_contract);
}
@ -752,13 +734,11 @@ void CommandLineInterface::compile()
m_options.compiler.estimateGas ||
m_options.compiler.outputs.asm_ ||
m_options.compiler.outputs.asmJson ||
m_options.compiler.outputs.opcodes ||
m_options.compiler.outputs.binary ||
m_options.compiler.outputs.binaryRuntime ||
(m_options.compiler.combinedJsonRequests && (
m_options.compiler.combinedJsonRequests->binary ||
m_options.compiler.combinedJsonRequests->binaryRuntime ||
m_options.compiler.combinedJsonRequests->opcodes ||
m_options.compiler.combinedJsonRequests->asm_ ||
m_options.compiler.combinedJsonRequests->generatedSources ||
m_options.compiler.combinedJsonRequests->generatedSourcesRuntime ||
@ -858,8 +838,6 @@ void CommandLineInterface::handleCombinedJSON()
contractData[g_strBinary] = m_compiler->object(contractName).toHex();
if (m_options.compiler.combinedJsonRequests->binaryRuntime && compilationSuccess)
contractData[g_strBinaryRuntime] = m_compiler->runtimeObject(contractName).toHex();
if (m_options.compiler.combinedJsonRequests->opcodes && compilationSuccess)
contractData[g_strOpcodes] = evmasm::disassemble(m_compiler->object(contractName).bytecode, m_options.output.evmVersion);
if (m_options.compiler.combinedJsonRequests->asm_ && compilationSuccess)
contractData[g_strAsm] = m_compiler->assemblyJSON(contractName);
if (m_options.compiler.combinedJsonRequests->storageLayout && compilationSuccess)

View File

@ -99,7 +99,6 @@ private:
void handleCombinedJSON();
void handleAst();
void handleBinary(std::string const& _contract);
void handleOpcode(std::string const& _contract);
void handleIR(std::string const& _contract);
void handleIRAst(std::string const& _contract);
void handleIROptimized(std::string const& _contract);

View File

@ -723,7 +723,6 @@ General Information)").c_str(),
(CompilerOutputs::componentName(&CompilerOutputs::astCompactJson).c_str(), "AST of all source files in a compact JSON format.")
(CompilerOutputs::componentName(&CompilerOutputs::asm_).c_str(), "EVM assembly of the contracts.")
(CompilerOutputs::componentName(&CompilerOutputs::asmJson).c_str(), "EVM assembly of the contracts in JSON format.")
(CompilerOutputs::componentName(&CompilerOutputs::opcodes).c_str(), "Opcodes of the contracts.")
(CompilerOutputs::componentName(&CompilerOutputs::binary).c_str(), "Binary of the contracts in hex.")
(CompilerOutputs::componentName(&CompilerOutputs::binaryRuntime).c_str(), "Binary of the runtime part of the contracts in hex.")
(CompilerOutputs::componentName(&CompilerOutputs::abi).c_str(), "ABI specification of the contracts.")

View File

@ -72,7 +72,6 @@ struct CompilerOutputs
{"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},
@ -92,7 +91,6 @@ struct CompilerOutputs
bool astCompactJson = false;
bool asm_ = false;
bool asmJson = false;
bool opcodes = false;
bool binary = false;
bool binaryRuntime = false;
bool abi = false;
@ -121,7 +119,6 @@ struct CombinedJsonRequests
{"metadata", &CombinedJsonRequests::metadata},
{"bin", &CombinedJsonRequests::binary},
{"bin-runtime", &CombinedJsonRequests::binaryRuntime},
{"opcodes", &CombinedJsonRequests::opcodes},
{"asm", &CombinedJsonRequests::asm_},
{"storage-layout", &CombinedJsonRequests::storageLayout},
{"generated-sources", &CombinedJsonRequests::generatedSources},
@ -142,7 +139,6 @@ struct CombinedJsonRequests
bool metadata = false;
bool binary = false;
bool binaryRuntime = false;
bool opcodes = false;
bool asm_ = false;
bool storageLayout = false;
bool generatedSources = false;

View File

@ -42,20 +42,19 @@
#include <string>
#include <vector>
using namespace std;
using namespace solidity::frontend;
using namespace solidity::test;
using namespace solidity::util;
using namespace solidity::langutil;
using PathSet = set<boost::filesystem::path>;
using PathSet = std::set<boost::filesystem::path>;
#define TEST_CASE_NAME (boost::unit_test::framework::current_test_case().p_name)
namespace
{
ostream& operator<<(ostream& _out, vector<ImportRemapper::Remapping> const& _remappings)
std::ostream& operator<<(std::ostream& _out, std::vector<ImportRemapper::Remapping> const& _remappings)
{
static auto remappingToString = [](auto const& _remapping)
{
@ -66,17 +65,17 @@ ostream& operator<<(ostream& _out, vector<ImportRemapper::Remapping> const& _rem
return _out;
}
ostream& operator<<(ostream& _out, map<string, string> const& _map)
std::ostream& operator<<(std::ostream& _out, std::map<std::string, std::string> const& _map)
{
_out << "{" << endl;
_out << "{" << std::endl;
for (auto const& [key, value]: _map)
_out << "" << key << ": " << value << "," << endl;
_out << "" << key << ": " << value << "," << std::endl;
_out << "}";
return _out;
}
ostream& operator<<(ostream& _out, PathSet const& _paths)
std::ostream& operator<<(std::ostream& _out, PathSet const& _paths)
{
static auto pathString = [](auto const& _path) { return _path.string(); };
@ -93,15 +92,15 @@ namespace boost::test_tools::tt_detail
// The recommended solution is to overload print_log_value<> struct and make it use our operator.
template<>
struct print_log_value<vector<ImportRemapper::Remapping>>
struct print_log_value<std::vector<ImportRemapper::Remapping>>
{
void operator()(std::ostream& _out, vector<ImportRemapper::Remapping> const& _value) { ::operator<<(_out, _value); }
void operator()(std::ostream& _out, std::vector<ImportRemapper::Remapping> const& _value) { ::operator<<(_out, _value); }
};
template<>
struct print_log_value<map<string, string>>
struct print_log_value<std::map<std::string, std::string>>
{
void operator()(std::ostream& _out, map<string, string> const& _value) { ::operator<<(_out, _value); }
void operator()(std::ostream& _out, std::map<std::string, std::string> const& _value) { ::operator<<(_out, _value); }
};
template<>
@ -149,7 +148,7 @@ BOOST_AUTO_TEST_CASE(version)
BOOST_AUTO_TEST_CASE(multiple_input_modes)
{
array<string, 9> inputModeOptions = {
std::array<std::string, 9> inputModeOptions = {
"--help",
"--license",
"--version",
@ -160,13 +159,13 @@ BOOST_AUTO_TEST_CASE(multiple_input_modes)
"--yul",
"--import-ast",
};
string expectedMessage =
std::string expectedMessage =
"The following options are mutually exclusive: "
"--help, --license, --version, --standard-json, --link, --assemble, --strict-assembly, --yul, --import-ast, --lsp. "
"Select at most one.";
for (string const& mode1: inputModeOptions)
for (string const& mode2: inputModeOptions)
for (std::string const& mode1: inputModeOptions)
for (std::string const& mode2: inputModeOptions)
if (mode1 != mode2)
BOOST_CHECK_EXCEPTION(
parseCommandLineAndReadInputFiles({"solc", mode1, mode2}),
@ -188,11 +187,11 @@ BOOST_AUTO_TEST_CASE(cli_input)
soltestAssert(expectedDir1.is_absolute() || expectedDir1.root_path() == "/", "");
soltestAssert(expectedDir2.is_absolute() || expectedDir2.root_path() == "/", "");
vector<ImportRemapper::Remapping> expectedRemappings = {
std::vector<ImportRemapper::Remapping> expectedRemappings = {
{"", "a", "b/c/d"},
{"a", "b", "c/d/e/"},
};
map<string, string> expectedSources = {
std::map<std::string, std::string> expectedSources = {
{"<stdin>", ""},
{(expectedDir1 / "input1.sol").generic_string(), ""},
{(expectedDir2 / "input2.sol").generic_string(), ""},
@ -233,7 +232,7 @@ BOOST_AUTO_TEST_CASE(cli_ignore_missing_some_files_exist)
soltestAssert(expectedDir1.is_absolute() || expectedDir1.root_path() == "/", "");
// NOTE: Allowed paths should not be added for skipped files.
map<string, string> expectedSources = {{(expectedDir1 / "input1.sol").generic_string(), ""}};
std::map<std::string, std::string> expectedSources = {{(expectedDir1 / "input1.sol").generic_string(), ""}};
PathSet expectedAllowedPaths = {boost::filesystem::canonical(tempDir1)};
OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles({
@ -254,7 +253,7 @@ BOOST_AUTO_TEST_CASE(cli_ignore_missing_no_files_exist)
{
TemporaryDirectory tempDir(TEST_CASE_NAME);
string expectedMessage =
std::string expectedMessage =
"\"" + (tempDir.path() / "input1.sol").string() + "\" is not found. Skipping.\n"
"\"" + (tempDir.path() / "input2.sol").string() + "\" is not found. Skipping.\n"
"All specified input files either do not exist or are not regular files.\n";
@ -273,7 +272,7 @@ BOOST_AUTO_TEST_CASE(cli_not_a_file)
{
TemporaryDirectory tempDir(TEST_CASE_NAME);
string expectedMessage = "\"" + tempDir.path().string() + "\" is not a valid file.";
std::string expectedMessage = "\"" + tempDir.path().string() + "\" is not a valid file.";
BOOST_CHECK_EXCEPTION(
parseCommandLineAndReadInputFiles({"solc", tempDir.path().string()}),
@ -330,7 +329,7 @@ BOOST_AUTO_TEST_CASE(standard_json_one_input_file)
TemporaryDirectory tempDir(TEST_CASE_NAME);
createFilesWithParentDirs({tempDir.path() / "input.json"});
vector<string> commandLine = {"solc", "--standard-json", (tempDir.path() / "input.json").string()};
std::vector<std::string> commandLine = {"solc", "--standard-json", (tempDir.path() / "input.json").string()};
OptionsReaderAndMessages result = parseCommandLineAndReadInputFiles(commandLine);
BOOST_TEST(result.success);
BOOST_TEST(result.stderrContent == "");
@ -342,7 +341,7 @@ BOOST_AUTO_TEST_CASE(standard_json_one_input_file)
BOOST_AUTO_TEST_CASE(standard_json_two_input_files)
{
string expectedMessage =
std::string expectedMessage =
"Too many input files for --standard-json.\n"
"Please either specify a single file name or provide its content on standard input.";
@ -355,7 +354,7 @@ BOOST_AUTO_TEST_CASE(standard_json_two_input_files)
BOOST_AUTO_TEST_CASE(standard_json_one_input_file_and_stdin)
{
string expectedMessage =
std::string expectedMessage =
"Too many input files for --standard-json.\n"
"Please either specify a single file name or provide its content on standard input.";
@ -371,7 +370,7 @@ BOOST_AUTO_TEST_CASE(standard_json_ignore_missing)
TemporaryDirectory tempDir(TEST_CASE_NAME);
// This option is pretty much useless Standard JSON mode.
string expectedMessage =
std::string expectedMessage =
"All specified input files either do not exist or are not regular files.";
BOOST_CHECK_EXCEPTION(
@ -388,7 +387,7 @@ BOOST_AUTO_TEST_CASE(standard_json_ignore_missing)
BOOST_AUTO_TEST_CASE(standard_json_remapping)
{
string expectedMessage =
std::string expectedMessage =
"Import remappings are not accepted on the command line in Standard JSON mode.\n"
"Please put them under 'settings.remappings' in the JSON input.";
@ -415,7 +414,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_no_base_path)
boost::filesystem::path expectedOtherDir = "/" / otherDirNoSymlinks.relative_path();
soltestAssert(expectedOtherDir.is_absolute() || expectedOtherDir.root_path() == "/", "");
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
"contract1.sol", // Relative path
"c/d/contract2.sol", // Relative path with subdirectories
@ -432,7 +431,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_no_base_path)
};
expectedOptions.modelChecker.initialize = true;
map<string, string> expectedSources = {
std::map<std::string, std::string> expectedSources = {
{"contract1.sol", ""},
{"c/d/contract2.sol", ""},
{"contract3.sol", ""},
@ -475,7 +474,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_base_path_same_as_work_dir)
soltestAssert(expectedWorkDir.is_absolute() || expectedWorkDir.root_path() == "/", "");
soltestAssert(expectedOtherDir.is_absolute() || expectedOtherDir.root_path() == "/", "");
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
"--base-path=" + currentDirNoSymlinks.string(),
"contract1.sol", // Relative path
@ -494,7 +493,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_base_path_same_as_work_dir)
expectedOptions.input.basePath = currentDirNoSymlinks;
expectedOptions.modelChecker.initialize = true;
map<string, string> expectedSources = {
std::map<std::string, std::string> expectedSources = {
{"contract1.sol", ""},
{"c/d/contract2.sol", ""},
{"contract3.sol", ""},
@ -544,7 +543,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_base_path_different_from_wor
soltestAssert(expectedOtherDir.is_absolute() || expectedOtherDir.root_path() == "/", "");
soltestAssert(expectedBaseDir.is_absolute() || expectedBaseDir.root_path() == "/", "");
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
"--base-path=" + baseDirNoSymlinks.string(),
"contract1.sol", // Relative path
@ -565,7 +564,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_base_path_different_from_wor
expectedOptions.input.basePath = baseDirNoSymlinks;
expectedOptions.modelChecker.initialize = true;
map<string, string> expectedSources = {
std::map<std::string, std::string> expectedSources = {
{expectedWorkDir.generic_string() + "/contract1.sol", ""},
{expectedWorkDir.generic_string() + "/c/d/contract2.sol", ""},
{expectedCurrentDir.generic_string() + "/contract3.sol", ""},
@ -610,7 +609,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_relative_base_path)
soltestAssert(expectedWorkDir.is_absolute() || expectedWorkDir.root_path() == "/", "");
soltestAssert(expectedOtherDir.is_absolute() || expectedOtherDir.root_path() == "/", "");
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
"--base-path=base",
"contract1.sol", // Relative path outside of base path
@ -633,7 +632,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_relative_base_path)
expectedOptions.input.basePath = "base";
expectedOptions.modelChecker.initialize = true;
map<string, string> expectedSources = {
std::map<std::string, std::string> expectedSources = {
{expectedWorkDir.generic_string() + "/contract1.sol", ""},
{"contract2.sol", ""},
{expectedWorkDir.generic_string() + "/contract3.sol", ""},
@ -667,7 +666,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_normalization_and_weird_name
TemporaryWorkingDirectory tempWorkDir(tempDir.path() / "x/y/z");
soltestAssert(tempDir.path().is_absolute(), "");
string uncPath = "//" + tempDir.path().relative_path().generic_string();
std::string uncPath = "//" + tempDir.path().relative_path().generic_string();
soltestAssert(FileReader::isUNCPath(uncPath), "");
boost::filesystem::path tempDirNoSymlinks = boost::filesystem::canonical(tempDir);
@ -675,7 +674,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_normalization_and_weird_name
boost::filesystem::path expectedWorkDir = "/" / boost::filesystem::current_path().relative_path();
soltestAssert(expectedWorkDir.is_absolute() || expectedWorkDir.root_path() == "/", "");
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
#if !defined(_WIN32)
@ -763,7 +762,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_normalization_and_weird_name
};
expectedOptions.modelChecker.initialize = true;
map<string, string> expectedSources = {
std::map<std::string, std::string> expectedSources = {
#if !defined(_WIN32)
{"file:/c/d/contract1.sol", ""},
{"file:/c/d/contract2.sol", ""},
@ -843,7 +842,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_symlinks)
boost::filesystem::path expectedWorkDir = "/" / boost::filesystem::current_path().relative_path();
soltestAssert(expectedWorkDir.is_absolute() || expectedWorkDir.root_path() == "/", "");
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
"--base-path=../r/sym/z/",
@ -863,7 +862,7 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_symlinks)
expectedOptions.input.basePath = "../r/sym/z/";
expectedOptions.modelChecker.initialize = true;
map<string, string> expectedSources = {
std::map<std::string, std::string> expectedSources = {
{"contract.sol", ""},
{(expectedWorkDir.parent_path() / "x/y/z/contract.sol").generic_string(), ""},
{"contract_symlink.sol", ""},
@ -893,14 +892,14 @@ BOOST_AUTO_TEST_CASE(cli_paths_to_source_unit_names_base_path_and_stdin)
boost::filesystem::path expectedWorkDir = "/" / boost::filesystem::current_path().relative_path();
vector<string> commandLine = {"solc", "--base-path=base", "-"};
std::vector<std::string> commandLine = {"solc", "--base-path=base", "-"};
CommandLineOptions expectedOptions;
expectedOptions.input.addStdin = true;
expectedOptions.input.basePath = "base";
expectedOptions.modelChecker.initialize = true;
map<string, string> expectedSources = {
std::map<std::string, std::string> expectedSources = {
{"<stdin>", ""},
};
FileReader::FileSystemPathSet expectedAllowedDirectories = {};
@ -922,7 +921,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths)
TemporaryDirectory tempDir({"base/", "include/", "lib/nested/"}, TEST_CASE_NAME);
TemporaryWorkingDirectory tempWorkDir(tempDir);
string const mainContractSource = withPreamble(
std::string const mainContractSource = withPreamble(
"import \"contract.sol\";\n"
"import \"contract_via_callback.sol\";\n"
"import \"include.sol\";\n"
@ -933,7 +932,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths)
"import \"lib_via_callback.sol\";\n"
);
string const onlyPreamble = withPreamble("");
std::string const onlyPreamble = withPreamble("");
createFilesWithParentDirs(
{
tempDir.path() / "base/contract.sol",
@ -952,7 +951,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths)
boost::filesystem::path canonicalWorkDir = boost::filesystem::canonical(tempDir);
boost::filesystem::path expectedWorkDir = "/" / canonicalWorkDir.relative_path();
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
"--no-color",
"--base-path=base/",
@ -983,7 +982,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths)
expectedOptions.formatting.coloredOutput = false;
expectedOptions.modelChecker.initialize = true;
map<string, string> expectedSources = {
std::map<std::string, std::string> expectedSources = {
{"main.sol", mainContractSource},
{"contract.sol", onlyPreamble},
{"contract_via_callback.sol", onlyPreamble},
@ -995,7 +994,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths)
{"lib_via_callback.sol", onlyPreamble},
};
vector<boost::filesystem::path> expectedIncludePaths = {
std::vector<boost::filesystem::path> expectedIncludePaths = {
expectedWorkDir / "include/",
expectedWorkDir / "lib/nested",
expectedWorkDir / "lib/",
@ -1008,11 +1007,11 @@ BOOST_AUTO_TEST_CASE(cli_include_paths)
canonicalWorkDir / "lib",
};
string const expectedStdoutContent = "Compiler run successful. No contracts to compile.\n";
std::string const expectedStdoutContent = "Compiler run successful. No contracts to compile.\n";
OptionsReaderAndMessages result = runCLI(commandLine, "");
BOOST_TEST(result.stderrContent == "");
if (SemVerVersion{string(VersionString)}.isPrerelease())
if (SemVerVersion{std::string(VersionString)}.isPrerelease())
BOOST_TEST(result.stdoutContent == "");
else
BOOST_TEST(result.stdoutContent == expectedStdoutContent);
@ -1026,16 +1025,16 @@ BOOST_AUTO_TEST_CASE(cli_include_paths)
BOOST_AUTO_TEST_CASE(cli_no_contracts_to_compile)
{
string const contractSource = R"(
std::string const contractSource = R"(
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
enum Status { test }
)";
string const expectedStdoutContent = "Compiler run successful. No contracts to compile.\n";
std::string const expectedStdoutContent = "Compiler run successful. No contracts to compile.\n";
OptionsReaderAndMessages result = runCLI({"solc", "-"}, contractSource);
if (SemVerVersion{string(VersionString)}.isPrerelease())
if (SemVerVersion{std::string(VersionString)}.isPrerelease())
BOOST_TEST(result.stdoutContent == "");
else
BOOST_TEST(result.stdoutContent == expectedStdoutContent);
@ -1044,17 +1043,17 @@ BOOST_AUTO_TEST_CASE(cli_no_contracts_to_compile)
BOOST_AUTO_TEST_CASE(cli_no_output)
{
string const contractSource = R"(
std::string const contractSource = R"(
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
abstract contract A {
function B() public virtual returns(uint);
})";
string const expectedStdoutContent = "Compiler run successful. No output generated.\n";
std::string const expectedStdoutContent = "Compiler run successful. No output generated.\n";
OptionsReaderAndMessages result = runCLI({"solc", "-"}, contractSource);
if (SemVerVersion{string(VersionString)}.isPrerelease())
if (SemVerVersion{std::string(VersionString)}.isPrerelease())
BOOST_TEST(result.stdoutContent == "");
else
BOOST_TEST(result.stdoutContent == expectedStdoutContent);
@ -1066,14 +1065,14 @@ BOOST_AUTO_TEST_CASE(standard_json_include_paths)
TemporaryDirectory tempDir({"base/", "include/", "lib/nested/"}, TEST_CASE_NAME);
TemporaryWorkingDirectory tempWorkDir(tempDir);
string const mainContractSource = withPreamble(
std::string const mainContractSource = withPreamble(
"import 'contract_via_callback.sol';\n"
"import 'include_via_callback.sol';\n"
"import 'nested_via_callback.sol';\n"
"import 'lib_via_callback.sol';\n"
);
string const standardJsonInput = R"(
std::string const standardJsonInput = R"(
{
"language": "Solidity",
"sources": {
@ -1082,7 +1081,7 @@ BOOST_AUTO_TEST_CASE(standard_json_include_paths)
}
)";
string const onlyPreamble = withPreamble("");
std::string const onlyPreamble = withPreamble("");
createFilesWithParentDirs(
{
tempDir.path() / "base/contract_via_callback.sol",
@ -1095,7 +1094,7 @@ BOOST_AUTO_TEST_CASE(standard_json_include_paths)
boost::filesystem::path expectedWorkDir = "/" / boost::filesystem::canonical(tempDir).relative_path();
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
"--base-path=base/",
"--include-path=include/",
@ -1119,14 +1118,14 @@ BOOST_AUTO_TEST_CASE(standard_json_include_paths)
// NOTE: Source code from Standard JSON does not end up in FileReader. This is not a problem
// because FileReader is only used once to initialize the compiler stack and after that
// its sources are irrelevant (even though the callback still stores everything it loads).
map<string, string> expectedSources = {
std::map<std::string, std::string> expectedSources = {
{"contract_via_callback.sol", onlyPreamble},
{"include_via_callback.sol", onlyPreamble},
{"nested_via_callback.sol", onlyPreamble},
{"lib_via_callback.sol", onlyPreamble},
};
vector<boost::filesystem::path> expectedIncludePaths = {
std::vector<boost::filesystem::path> expectedIncludePaths = {
expectedWorkDir / "include/",
expectedWorkDir / "lib/nested",
expectedWorkDir / "lib/",
@ -1137,15 +1136,15 @@ BOOST_AUTO_TEST_CASE(standard_json_include_paths)
OptionsReaderAndMessages result = runCLI(commandLine, standardJsonInput);
Json::Value parsedStdout;
string jsonParsingErrors;
std::string jsonParsingErrors;
BOOST_TEST(util::jsonParseStrict(result.stdoutContent, parsedStdout, &jsonParsingErrors));
BOOST_TEST(jsonParsingErrors == "");
for (Json::Value const& errorDict: parsedStdout["errors"])
// The error list might contain pre-release compiler warning
BOOST_TEST(errorDict["severity"] != "error");
BOOST_TEST(
(parsedStdout["sources"].getMemberNames() | ranges::to<set>) ==
(expectedSources | ranges::views::keys | ranges::to<set>) + set<string>{"main.sol"}
(parsedStdout["sources"].getMemberNames() | ranges::to<std::set>) ==
(expectedSources | ranges::views::keys | ranges::to<std::set>) + std::set<std::string>{"main.sol"}
);
BOOST_REQUIRE(result.success);
@ -1162,7 +1161,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_empty_path)
TemporaryWorkingDirectory tempWorkDir(tempDir);
createFilesWithParentDirs({tempDir.path() / "base/main.sol"});
string expectedMessage = "Empty values are not allowed in --include-path.";
std::string expectedMessage = "Empty values are not allowed in --include-path.";
BOOST_CHECK_EXCEPTION(
parseCommandLineAndReadInputFiles({
@ -1183,7 +1182,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_without_base_path)
TemporaryWorkingDirectory tempWorkDir(tempDir);
createFilesWithParentDirs({tempDir.path() / "contract.sol"});
string expectedMessage = "--include-path option requires a non-empty base path.";
std::string expectedMessage = "--include-path option requires a non-empty base path.";
BOOST_CHECK_EXCEPTION(
parseCommandLineAndReadInputFiles({"solc", "--include-path", "include/", "contract.sol"}),
@ -1205,7 +1204,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_should_detect_source_unit_name_collisions
boost::filesystem::path expectedWorkDir = "/" / boost::filesystem::canonical(tempDir).relative_path();
string expectedMessage =
std::string expectedMessage =
"Source unit name collision detected. "
"The specified values of base path and/or include paths would result in multiple "
"input files being assigned the same source unit name:\n"
@ -1253,7 +1252,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_should_detect_source_unit_name_collisions
{
// No conflict if files with the same name exist but only one is given to the compiler.
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
"--base-path=dir3/",
"--include-path=dir1/",
@ -1268,7 +1267,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_should_detect_source_unit_name_collisions
{
// The same file specified multiple times is not a conflict.
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
"--base-path=dir3/",
"--include-path=dir1/",
@ -1292,7 +1291,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_should_allow_duplicate_paths)
boost::filesystem::path expectedWorkDir = "/" / boost::filesystem::canonical(tempDir).relative_path();
boost::filesystem::path expectedTempDir = "/" / tempDir.path().relative_path();
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
"--base-path=dir1/",
"--include-path", "dir1",
@ -1308,7 +1307,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_should_allow_duplicate_paths)
};
// Duplicates do not affect the result but are not removed from the include path list.
vector<boost::filesystem::path> expectedIncludePaths = {
std::vector<boost::filesystem::path> expectedIncludePaths = {
expectedWorkDir / "dir1",
expectedWorkDir / "dir1",
expectedWorkDir / "dir1/",
@ -1335,13 +1334,13 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_ambiguous_import)
TemporaryWorkingDirectory tempWorkDir(tempDir);
// Ambiguous: both base/contract.sol and include/contract.sol match the import.
string const mainContractSource = withPreamble("import \"contract.sol\";");
std::string const mainContractSource = withPreamble("import \"contract.sol\";");
createFilesWithParentDirs({"base/contract.sol", "include/contract.sol"}, withPreamble(""));
boost::filesystem::path expectedWorkDir = "/" / boost::filesystem::canonical(tempDir).relative_path();
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
"--no-color",
"--base-path=base/",
@ -1349,7 +1348,7 @@ BOOST_AUTO_TEST_CASE(cli_include_paths_ambiguous_import)
"-",
};
string expectedMessage =
std::string expectedMessage =
"Error: Source \"contract.sol\" not found: Ambiguous import. "
"Multiple matching files found inside base path and/or include paths: \"" +
(expectedWorkDir / "base/contract.sol").generic_string() + "\", \"" +

View File

@ -47,9 +47,9 @@ using namespace solidity::yul;
namespace
{
CommandLineOptions parseCommandLine(vector<string> const& _commandLine)
CommandLineOptions parseCommandLine(std::vector<std::string> const& _commandLine)
{
vector<char const*> argv = test::makeArgv(_commandLine);
std::vector<char const*> argv = test::makeArgv(_commandLine);
CommandLineParser cliParser;
cliParser.parse(static_cast<int>(_commandLine.size()), argv.data());
@ -79,7 +79,7 @@ BOOST_AUTO_TEST_CASE(no_options)
BOOST_AUTO_TEST_CASE(help_license_version)
{
map<string, InputMode> expectedModePerOption = {
std::map<std::string, InputMode> expectedModePerOption = {
{"--help", InputMode::Help},
{"--license", InputMode::License},
{"--version", InputMode::Version},
@ -130,11 +130,11 @@ BOOST_AUTO_TEST_CASE(cli_mode_options)
"--libraries="
"dir1/file1.sol:L=0x1234567890123456789012345678901234567890,"
"dir2/file2.sol:L=0x1111122222333334444455555666667777788888",
"--ast-compact-json", "--asm", "--asm-json", "--opcodes", "--bin", "--bin-runtime", "--abi",
"--ast-compact-json", "--asm", "--asm-json", "--bin", "--bin-runtime", "--abi",
"--ir", "--ir-ast-json", "--ir-optimized", "--ir-optimized-ast-json", "--hashes", "--userdoc", "--devdoc", "--metadata", "--storage-layout",
"--gas",
"--combined-json="
"abi,metadata,bin,bin-runtime,opcodes,asm,storage-layout,generated-sources,generated-sources-runtime,"
"abi,metadata,bin,bin-runtime,asm,storage-layout,generated-sources,generated-sources-runtime,"
"srcmap,srcmap-runtime,function-debug,function-debug-runtime,hashes,devdoc,userdoc,ast",
"--metadata-hash=swarm",
"--metadata-literal",
@ -193,14 +193,13 @@ BOOST_AUTO_TEST_CASE(cli_mode_options)
true, true, true, true, true,
true, true, true, true, true,
true, true, true, true, true,
true,
};
expectedOptions.compiler.estimateGas = true;
expectedOptions.compiler.combinedJsonRequests = {
true, true, true, true, true,
true, true, true, true, true,
true, true, true, true, true,
true, true,
true,
};
expectedOptions.metadata.hash = CompilerStack::MetadataHash::Bzzr1;
expectedOptions.metadata.literalSources = true;
@ -264,7 +263,7 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options)
for (auto const& [assemblyOptions, expectedMachine, expectedLanguage]: allowedCombinations)
{
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
"contract.yul",
"/tmp/projects/token.yul",
@ -298,7 +297,7 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options)
};
commandLine += assemblyOptions;
if (expectedLanguage == YulStack::Language::StrictAssembly)
commandLine += vector<string>{
commandLine += std::vector<std::string>{
"--optimize",
"--optimize-runs=1000",
"--yul-optimizations=agf",
@ -351,7 +350,7 @@ BOOST_AUTO_TEST_CASE(assembly_mode_options)
BOOST_AUTO_TEST_CASE(standard_json_mode_options)
{
vector<string> commandLine = {
std::vector<std::string> commandLine = {
"solc",
"input.json",
"--standard-json",
@ -420,16 +419,16 @@ BOOST_AUTO_TEST_CASE(invalid_options_input_modes_combinations)
};
for (auto const& [optionName, inputModes]: invalidOptionInputModeCombinations)
for (string const& inputMode: inputModes)
for (std::string const& inputMode: inputModes)
{
stringstream serr;
size_t separatorPosition = optionName.find("=");
string optionNameWithoutValue = optionName.substr(0, separatorPosition);
std::string optionNameWithoutValue = optionName.substr(0, separatorPosition);
soltestAssert(!optionNameWithoutValue.empty());
vector<string> commandLine = {"solc", optionName, "file", inputMode};
std::vector<std::string> commandLine = {"solc", optionName, "file", inputMode};
string expectedMessage = "The following options are not supported in the current input mode: " + optionNameWithoutValue;
std::string expectedMessage = "The following options are not supported in the current input mode: " + optionNameWithoutValue;
auto hasCorrectMessage = [&](CommandLineValidationError const& _exception) { return _exception.what() == expectedMessage; };
BOOST_CHECK_EXCEPTION(parseCommandLine(commandLine), CommandLineValidationError, hasCorrectMessage);
@ -445,7 +444,7 @@ BOOST_AUTO_TEST_CASE(optimizer_flags)
OptimiserSettings evmasmOnly = OptimiserSettings::standard();
evmasmOnly.runYulOptimiser = false;
map<vector<string>, OptimiserSettings> settingsMap = {
std::map<std::vector<std::string>, OptimiserSettings> settingsMap = {
{{}, OptimiserSettings::minimal()},
{{"--optimize"}, OptimiserSettings::standard()},
{{"--no-optimize-yul"}, OptimiserSettings::minimal()},
@ -454,7 +453,7 @@ BOOST_AUTO_TEST_CASE(optimizer_flags)
{{"--optimize", "--optimize-yul"}, OptimiserSettings::standard()},
};
map<InputMode, string> inputModeFlagMap = {
std::map<InputMode, std::string> inputModeFlagMap = {
{InputMode::Compiler, ""},
{InputMode::CompilerWithASTImport, "--import-ast"},
{InputMode::Assembler, "--strict-assembly"},
@ -463,7 +462,7 @@ BOOST_AUTO_TEST_CASE(optimizer_flags)
for (auto const& [inputMode, inputModeFlag]: inputModeFlagMap)
for (auto const& [optimizerFlags, expectedOptimizerSettings]: settingsMap)
{
vector<string> commandLine = {"solc", inputModeFlag, "file"};
std::vector<std::string> commandLine = {"solc", inputModeFlag, "file"};
commandLine += optimizerFlags;
BOOST_CHECK(parseCommandLine(commandLine).optimiserSettings() == expectedOptimizerSettings);
}
@ -478,7 +477,7 @@ BOOST_AUTO_TEST_CASE(default_optimiser_sequence)
BOOST_AUTO_TEST_CASE(valid_optimiser_sequences)
{
vector<string> validSequenceInputs {
std::vector<std::string> validSequenceInputs {
":", // Empty optimization sequence and empty cleanup sequence
":fDn", // Empty optimization sequence and specified cleanup sequence
"dhfoDgvulfnTUtnIf:", // Specified optimization sequence and empty cleanup sequence
@ -513,7 +512,7 @@ BOOST_AUTO_TEST_CASE(valid_optimiser_sequences)
BOOST_AUTO_TEST_CASE(invalid_optimiser_sequences)
{
vector<string> const invalidSequenceInputs {
std::vector<std::string> const invalidSequenceInputs {
"abcdefg{hijklmno}pqr[st]uvwxyz", // Invalid abbreviation
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["
@ -531,7 +530,7 @@ BOOST_AUTO_TEST_CASE(invalid_optimiser_sequences)
"dhfoDgvulfnTU:tnIf:fdN" // Too many cleanup sequence delimiters
};
vector<string> const expectedErrorMessages {
std::vector<std::string> const expectedErrorMessages {
"'b' is not a valid step abbreviation",
"Brackets nested too deep",
"Unbalanced brackets",
@ -542,12 +541,12 @@ BOOST_AUTO_TEST_CASE(invalid_optimiser_sequences)
BOOST_CHECK_EQUAL(invalidSequenceInputs.size(), expectedErrorMessages.size());
string const baseExpectedErrorMessage = "Invalid optimizer step sequence in --yul-optimizations: ";
std::string const baseExpectedErrorMessage = "Invalid optimizer step sequence in --yul-optimizations: ";
for (size_t i = 0; i < invalidSequenceInputs.size(); ++i)
{
vector<string> const commandLineOptions = {"solc", "contract.sol", "--optimize", "--yul-optimizations=" + invalidSequenceInputs[i]};
string const expectedErrorMessage = baseExpectedErrorMessage + expectedErrorMessages[i];
std::vector<std::string> const commandLineOptions = {"solc", "contract.sol", "--optimize", "--yul-optimizations=" + invalidSequenceInputs[i]};
std::string const expectedErrorMessage = baseExpectedErrorMessage + expectedErrorMessages[i];
auto hasCorrectMessage = [&](CommandLineValidationError const& _exception) { return _exception.what() == expectedErrorMessage; };
BOOST_CHECK_EXCEPTION(parseCommandLine(commandLineOptions), CommandLineValidationError, hasCorrectMessage);
}