mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Relative paths in import directives.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <libsolidity/ast/AST.h>
|
||||
#include <libsolidity/parsing/Scanner.h>
|
||||
#include <libsolidity/parsing/Parser.h>
|
||||
@@ -367,7 +368,7 @@ void CompilerStack::resolveImports()
|
||||
vector<Source const*> sourceOrder;
|
||||
set<Source const*> sourcesSeen;
|
||||
|
||||
function<void(Source const*)> toposort = [&](Source const* _source)
|
||||
function<void(string const&, Source const*)> toposort = [&](string const& _sourceName, Source const* _source)
|
||||
{
|
||||
if (sourcesSeen.count(_source))
|
||||
return;
|
||||
@@ -375,26 +376,44 @@ void CompilerStack::resolveImports()
|
||||
for (ASTPointer<ASTNode> const& node: _source->ast->nodes())
|
||||
if (ImportDirective const* import = dynamic_cast<ImportDirective*>(node.get()))
|
||||
{
|
||||
string const& id = import->identifier();
|
||||
if (!m_sources.count(id))
|
||||
string path = absolutePath(import->identifier(), _sourceName);
|
||||
import->annotation().absolutePath = path;
|
||||
if (!m_sources.count(path))
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error(Error::Type::ParserError)
|
||||
<< errinfo_sourceLocation(import->location())
|
||||
<< errinfo_comment("Source not found.")
|
||||
);
|
||||
|
||||
toposort(&m_sources[id]);
|
||||
toposort(path, &m_sources[path]);
|
||||
}
|
||||
sourceOrder.push_back(_source);
|
||||
};
|
||||
|
||||
for (auto const& sourcePair: m_sources)
|
||||
if (!sourcePair.second.isLibrary)
|
||||
toposort(&sourcePair.second);
|
||||
toposort(sourcePair.first, &sourcePair.second);
|
||||
|
||||
swap(m_sourceOrder, sourceOrder);
|
||||
}
|
||||
|
||||
string CompilerStack::absolutePath(string const& _path, string const& _reference) const
|
||||
{
|
||||
// Anything that does not start with `.` is an absolute path.
|
||||
if (_path.empty() || _path.front() != '.')
|
||||
return _path;
|
||||
using path = boost::filesystem::path;
|
||||
path p(_path);
|
||||
path result(_reference);
|
||||
result.remove_filename();
|
||||
for (path::iterator it = p.begin(); it != p.end(); ++it)
|
||||
if (*it == "..")
|
||||
result = result.parent_path();
|
||||
else if (*it != ".")
|
||||
result /= *it;
|
||||
return result.string();
|
||||
}
|
||||
|
||||
void CompilerStack::compileContract(
|
||||
bool _optimize,
|
||||
unsigned _runs,
|
||||
|
||||
Reference in New Issue
Block a user