mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add --include-path option
This commit is contained in:
@@ -24,30 +24,54 @@
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
#include <range/v3/range/conversion.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
using solidity::frontend::ReadCallback;
|
||||
using solidity::langutil::InternalCompilerError;
|
||||
using solidity::util::errinfo_comment;
|
||||
using solidity::util::readFileAsString;
|
||||
using std::reference_wrapper;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
namespace solidity::frontend
|
||||
{
|
||||
|
||||
FileReader::FileReader(
|
||||
boost::filesystem::path _basePath,
|
||||
vector<boost::filesystem::path> const& _includePaths,
|
||||
FileSystemPathSet _allowedDirectories
|
||||
):
|
||||
m_allowedDirectories(std::move(_allowedDirectories)),
|
||||
m_sourceCodes()
|
||||
{
|
||||
setBasePath(_basePath);
|
||||
for (boost::filesystem::path const& includePath: _includePaths)
|
||||
addIncludePath(includePath);
|
||||
|
||||
for (boost::filesystem::path const& allowedDir: m_allowedDirectories)
|
||||
solAssert(!allowedDir.empty(), "");
|
||||
}
|
||||
|
||||
void FileReader::setBasePath(boost::filesystem::path const& _path)
|
||||
{
|
||||
m_basePath = (_path.empty() ? "" : normalizeCLIPathForVFS(_path));
|
||||
if (_path.empty())
|
||||
{
|
||||
// Empty base path is a special case that does not make sense when include paths are used.
|
||||
solAssert(m_includePaths.empty(), "");
|
||||
m_basePath = "";
|
||||
}
|
||||
else
|
||||
m_basePath = normalizeCLIPathForVFS(_path);
|
||||
}
|
||||
|
||||
void FileReader::addIncludePath(boost::filesystem::path const& _path)
|
||||
{
|
||||
solAssert(!m_basePath.empty(), "");
|
||||
solAssert(!_path.empty(), "");
|
||||
m_includePaths.push_back(normalizeCLIPathForVFS(_path));
|
||||
}
|
||||
|
||||
void FileReader::allowDirectory(boost::filesystem::path _path)
|
||||
@@ -58,10 +82,7 @@ void FileReader::allowDirectory(boost::filesystem::path _path)
|
||||
|
||||
void FileReader::setSource(boost::filesystem::path const& _path, SourceCode _source)
|
||||
{
|
||||
boost::filesystem::path normalizedPath = normalizeCLIPathForVFS(_path);
|
||||
boost::filesystem::path prefix = (m_basePath.empty() ? normalizeCLIPathForVFS(".") : m_basePath);
|
||||
|
||||
m_sourceCodes[stripPrefixIfPresent(prefix, normalizedPath).generic_string()] = std::move(_source);
|
||||
m_sourceCodes[cliPathToSourceUnitName(_path)] = std::move(_source);
|
||||
}
|
||||
|
||||
void FileReader::setStdin(SourceCode _source)
|
||||
@@ -87,8 +108,20 @@ ReadCallback::Result FileReader::readFile(string const& _kind, string const& _so
|
||||
if (strippedSourceUnitName.find("file://") == 0)
|
||||
strippedSourceUnitName.erase(0, 7);
|
||||
|
||||
auto canonicalPath = normalizeCLIPathForVFS(m_basePath / strippedSourceUnitName, SymlinkResolution::Enabled);
|
||||
vector<reference_wrapper<boost::filesystem::path>> prefixes = {m_basePath};
|
||||
prefixes += (m_includePaths | ranges::to<vector<reference_wrapper<boost::filesystem::path>>>);
|
||||
|
||||
boost::filesystem::path canonicalPath;
|
||||
for (auto const& prefix: prefixes)
|
||||
{
|
||||
canonicalPath = normalizeCLIPathForVFS(prefix / strippedSourceUnitName, SymlinkResolution::Enabled);
|
||||
|
||||
if (boost::filesystem::exists(canonicalPath))
|
||||
break;
|
||||
}
|
||||
|
||||
FileSystemPathSet extraAllowedPaths = {m_basePath.empty() ? "." : m_basePath};
|
||||
extraAllowedPaths += m_includePaths;
|
||||
|
||||
bool isAllowed = false;
|
||||
for (boost::filesystem::path const& allowedDir: m_allowedDirectories + extraAllowedPaths)
|
||||
@@ -126,6 +159,23 @@ ReadCallback::Result FileReader::readFile(string const& _kind, string const& _so
|
||||
}
|
||||
}
|
||||
|
||||
string FileReader::cliPathToSourceUnitName(boost::filesystem::path const& _cliPath)
|
||||
{
|
||||
vector<boost::filesystem::path> prefixes = {m_basePath.empty() ? normalizeCLIPathForVFS(".") : m_basePath};
|
||||
prefixes += m_includePaths;
|
||||
|
||||
boost::filesystem::path normalizedPath = normalizeCLIPathForVFS(_cliPath);
|
||||
for (boost::filesystem::path const& prefix: prefixes)
|
||||
if (isPathPrefix(prefix, normalizedPath))
|
||||
{
|
||||
// Multiple prefixes can potentially match the path. We take the first one.
|
||||
normalizedPath = stripPrefixIfPresent(prefix, normalizedPath);
|
||||
break;
|
||||
}
|
||||
|
||||
return normalizedPath.generic_string();
|
||||
}
|
||||
|
||||
boost::filesystem::path FileReader::normalizeCLIPathForVFS(
|
||||
boost::filesystem::path const& _path,
|
||||
SymlinkResolution _symlinkResolution
|
||||
|
||||
@@ -44,13 +44,20 @@ public:
|
||||
Enabled, ///< Follow symbolic links. The path should contain no symlinks.
|
||||
};
|
||||
|
||||
/// Constructs a FileReader with a base path and a set of allowed directories that
|
||||
/// will be used when requesting files from this file reader instance.
|
||||
explicit FileReader(boost::filesystem::path _basePath = {}, FileSystemPathSet _allowedDirectories = {});
|
||||
/// Constructs a FileReader with a base path and sets of include paths and allowed directories
|
||||
/// that will be used when requesting files from this file reader instance.
|
||||
explicit FileReader(
|
||||
boost::filesystem::path _basePath = {},
|
||||
std::vector<boost::filesystem::path> const& _includePaths = {},
|
||||
FileSystemPathSet _allowedDirectories = {}
|
||||
);
|
||||
|
||||
void setBasePath(boost::filesystem::path const& _path);
|
||||
boost::filesystem::path const& basePath() const noexcept { return m_basePath; }
|
||||
|
||||
void addIncludePath(boost::filesystem::path const& _path);
|
||||
std::vector<boost::filesystem::path> const& includePaths() const noexcept { return m_includePaths; }
|
||||
|
||||
void allowDirectory(boost::filesystem::path _path);
|
||||
FileSystemPathSet const& allowedDirectories() const noexcept { return m_allowedDirectories; }
|
||||
|
||||
@@ -85,6 +92,10 @@ public:
|
||||
return [this](std::string const& _kind, std::string const& _path) { return readFile(_kind, _path); };
|
||||
}
|
||||
|
||||
/// Creates a source unit name by normalizing a path given on the command line and, if possible,
|
||||
/// making it relative to base path or one of the include directories.
|
||||
std::string cliPathToSourceUnitName(boost::filesystem::path const& _cliPath);
|
||||
|
||||
/// Normalizes a filesystem path to make it include all components up to the filesystem root,
|
||||
/// remove small, inconsequential differences that do not affect the meaning and make it look
|
||||
/// the same on all platforms (if possible).
|
||||
@@ -130,6 +141,9 @@ private:
|
||||
/// Base path, used for resolving relative paths in imports.
|
||||
boost::filesystem::path m_basePath;
|
||||
|
||||
/// Additional directories used for resolving relative paths in imports.
|
||||
std::vector<boost::filesystem::path> m_includePaths;
|
||||
|
||||
/// list of allowed directories to read files from
|
||||
FileSystemPathSet m_allowedDirectories;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user