diff options
author | chriseth <c@ethdev.com> | 2015-12-15 18:43:59 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-12-15 18:43:59 +0800 |
commit | 591a4f1ff44af20fce9bafebf0fa0607e2bdfcc0 (patch) | |
tree | 282c36887814420e2fa86e132587ec9f192f30ad /libsolidity/interface | |
parent | 98684cca9035c754adcdc99fd196716cb7802efd (diff) | |
parent | 53da78e6091d9bb0229b4a54a0042e23487550db (diff) | |
download | dexon-solidity-591a4f1ff44af20fce9bafebf0fa0607e2bdfcc0.tar dexon-solidity-591a4f1ff44af20fce9bafebf0fa0607e2bdfcc0.tar.gz dexon-solidity-591a4f1ff44af20fce9bafebf0fa0607e2bdfcc0.tar.bz2 dexon-solidity-591a4f1ff44af20fce9bafebf0fa0607e2bdfcc0.tar.lz dexon-solidity-591a4f1ff44af20fce9bafebf0fa0607e2bdfcc0.tar.xz dexon-solidity-591a4f1ff44af20fce9bafebf0fa0607e2bdfcc0.tar.zst dexon-solidity-591a4f1ff44af20fce9bafebf0fa0607e2bdfcc0.zip |
Merge pull request #288 from chriseth/import_contexts
Do not clutter importee when importing.
Diffstat (limited to 'libsolidity/interface')
-rw-r--r-- | libsolidity/interface/CompilerStack.cpp | 35 | ||||
-rw-r--r-- | libsolidity/interface/CompilerStack.h | 2 |
2 files changed, 32 insertions, 5 deletions
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 18eec0a2..7f097523 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -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> @@ -103,12 +104,14 @@ bool CompilerStack::parse() m_errors.clear(); m_parseSuccessful = false; + map<string, SourceUnit const*> sourceUnitsByName; for (auto& sourcePair: m_sources) { sourcePair.second.scanner->reset(); sourcePair.second.ast = Parser(m_errors).parse(sourcePair.second.scanner); if (!sourcePair.second.ast) solAssert(!Error::containsOnlyWarnings(m_errors), "Parser returned null but did not report error."); + sourceUnitsByName[sourcePair.first] = sourcePair.second.ast.get(); } if (!Error::containsOnlyWarnings(m_errors)) // errors while parsing. sould stop before type checking @@ -129,6 +132,10 @@ bool CompilerStack::parse() return false; for (Source const* source: m_sourceOrder) + if (!resolver.performImports(*source->ast, sourceUnitsByName)) + return false; + + for (Source const* source: m_sourceOrder) for (ASTPointer<ASTNode> const& node: source->ast->nodes()) if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) { @@ -361,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; @@ -369,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, diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 0473d58b..3e6dc456 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -199,6 +199,8 @@ private: }; void resolveImports(); + /// @returns the absolute path corresponding to @a _path relative to @a _reference. + std::string absolutePath(std::string const& _path, std::string const& _reference) const; /// Compile a single contract and put the result in @a _compiledContracts. void compileContract( bool _optimize, |