Refactor parsing of remappings to remove duplication and improve readability

This commit is contained in:
Kamil Śliwak 2021-07-23 23:43:10 +02:00
parent b9b35a0def
commit f0dceffe1d
3 changed files with 40 additions and 29 deletions

View File

@ -20,10 +20,12 @@
#include <liblangutil/Exceptions.h>
using std::equal;
using std::find;
using std::move;
using std::nullopt;
using std::optional;
using std::string;
using std::string;
using std::string_view;
using std::vector;
namespace solidity::frontend
@ -77,24 +79,29 @@ SourceUnitName ImportRemapper::apply(ImportPath const& _path, string const& _con
return path;
}
optional<ImportRemapper::Remapping> ImportRemapper::parseRemapping(string const& _remapping)
bool ImportRemapper::isRemapping(string_view _input)
{
auto eq = find(_remapping.begin(), _remapping.end(), '=');
if (eq == _remapping.end())
return {};
return _input.find("=") != string::npos;
}
auto colon = find(_remapping.begin(), eq, ':');
optional<ImportRemapper::Remapping> ImportRemapper::parseRemapping(string_view _input)
{
auto equals = find(_input.cbegin(), _input.cend(), '=');
if (equals == _input.end())
return nullopt;
Remapping r;
auto const colon = find(_input.cbegin(), equals, ':');
r.context = colon == eq ? string() : string(_remapping.begin(), colon);
r.prefix = colon == eq ? string(_remapping.begin(), eq) : string(colon + 1, eq);
r.target = string(eq + 1, _remapping.end());
Remapping remapping{
(colon == equals ? "" : string(_input.cbegin(), colon)),
(colon == equals ? string(_input.cbegin(), equals) : string(colon + 1, equals)),
string(equals + 1, _input.cend()),
};
if (r.prefix.empty())
return {};
if (remapping.prefix.empty())
return nullopt;
return r;
return remapping;
}
}

View File

@ -56,8 +56,11 @@ public:
SourceUnitName apply(ImportPath const& _path, std::string const& _context) const;
// Parses a remapping of the format "context:prefix=target".
static std::optional<Remapping> parseRemapping(std::string const& _remapping);
/// @returns true if the string can be parsed as a remapping
static bool isRemapping(std::string_view _input);
/// Parses a remapping of the format "context:prefix=target".
static std::optional<Remapping> parseRemapping(std::string_view _input);
private:
/// list of path prefix remappings, e.g. mylibrary: github.com/ethereum = /usr/local/ethereum

View File

@ -338,11 +338,17 @@ bool CommandLineParser::parseInputPathsAndRemappings()
m_options.input.ignoreMissingFiles = (m_args.count(g_strIgnoreMissingFiles) > 0);
if (m_args.count(g_strInputFile))
for (string path: m_args[g_strInputFile].as<vector<string>>())
for (string const& positionalArg: m_args[g_strInputFile].as<vector<string>>())
{
auto eq = find(path.begin(), path.end(), '=');
if (eq != path.end())
if (ImportRemapper::isRemapping(positionalArg))
{
optional<ImportRemapper::Remapping> remapping = ImportRemapper::parseRemapping(positionalArg);
if (!remapping.has_value())
{
serr() << "Invalid remapping: \"" << positionalArg << "\"." << endl;
return false;
}
if (m_options.input.mode == InputMode::StandardJson)
{
serr() << "Import remappings are not accepted on the command line in Standard JSON mode." << endl;
@ -350,21 +356,16 @@ bool CommandLineParser::parseInputPathsAndRemappings()
return false;
}
if (auto r = ImportRemapper::parseRemapping(path))
m_options.input.remappings.emplace_back(std::move(*r));
else
{
serr() << "Invalid remapping: \"" << path << "\"." << endl;
return false;
}
boost::filesystem::path remappingDir = remapping->target;
remappingDir.remove_filename();
m_options.input.allowedDirectories.insert(remappingDir);
string remappingTarget(eq + 1, path.end());
m_options.input.allowedDirectories.insert(boost::filesystem::path(remappingTarget).remove_filename());
m_options.input.remappings.emplace_back(move(remapping.value()));
}
else if (path == "-")
else if (positionalArg == "-")
m_options.input.addStdin = true;
else
m_options.input.paths.insert(path);
m_options.input.paths.insert(positionalArg);
}
if (m_options.input.mode == InputMode::StandardJson)