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

View File

@ -56,8 +56,11 @@ public:
SourceUnitName apply(ImportPath const& _path, std::string const& _context) const; SourceUnitName apply(ImportPath const& _path, std::string const& _context) const;
// Parses a remapping of the format "context:prefix=target". /// @returns true if the string can be parsed as a remapping
static std::optional<Remapping> parseRemapping(std::string const& _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: private:
/// list of path prefix remappings, e.g. mylibrary: github.com/ethereum = /usr/local/ethereum /// 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); m_options.input.ignoreMissingFiles = (m_args.count(g_strIgnoreMissingFiles) > 0);
if (m_args.count(g_strInputFile)) 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 (ImportRemapper::isRemapping(positionalArg))
if (eq != path.end())
{ {
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) if (m_options.input.mode == InputMode::StandardJson)
{ {
serr() << "Import remappings are not accepted on the command line in Standard JSON mode." << endl; serr() << "Import remappings are not accepted on the command line in Standard JSON mode." << endl;
@ -350,21 +356,16 @@ bool CommandLineParser::parseInputPathsAndRemappings()
return false; return false;
} }
if (auto r = ImportRemapper::parseRemapping(path)) boost::filesystem::path remappingDir = remapping->target;
m_options.input.remappings.emplace_back(std::move(*r)); remappingDir.remove_filename();
else m_options.input.allowedDirectories.insert(remappingDir);
{
serr() << "Invalid remapping: \"" << path << "\"." << endl;
return false;
}
string remappingTarget(eq + 1, path.end()); m_options.input.remappings.emplace_back(move(remapping.value()));
m_options.input.allowedDirectories.insert(boost::filesystem::path(remappingTarget).remove_filename());
} }
else if (path == "-") else if (positionalArg == "-")
m_options.input.addStdin = true; m_options.input.addStdin = true;
else else
m_options.input.paths.insert(path); m_options.input.paths.insert(positionalArg);
} }
if (m_options.input.mode == InputMode::StandardJson) if (m_options.input.mode == InputMode::StandardJson)