diff options
author | chriseth <c@ethdev.com> | 2015-12-15 22:46:03 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-12-18 19:46:56 +0800 |
commit | 603dc58040e62ef99d0a10084340dd4548a438a8 (patch) | |
tree | 2c9246af514f8023117800bd8675703fc8d02fb4 /libsolidity/analysis | |
parent | d3c459b5a99715c96733825f78d63cc57265ee3c (diff) | |
download | dexon-solidity-603dc58040e62ef99d0a10084340dd4548a438a8.tar.gz dexon-solidity-603dc58040e62ef99d0a10084340dd4548a438a8.tar.zst dexon-solidity-603dc58040e62ef99d0a10084340dd4548a438a8.zip |
Simple aliasing during import.
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r-- | libsolidity/analysis/NameAndTypeResolver.cpp | 25 | ||||
-rw-r--r-- | libsolidity/analysis/NameAndTypeResolver.h | 8 |
2 files changed, 24 insertions, 9 deletions
diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 02e4d7ab..92347bfc 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -46,14 +46,16 @@ NameAndTypeResolver::NameAndTypeResolver( bool NameAndTypeResolver::registerDeclarations(SourceUnit& _sourceUnit) { - solAssert(!m_scopes[&_sourceUnit], ""); - m_scopes[&_sourceUnit].reset(new DeclarationContainer(nullptr, m_scopes[nullptr].get())); + if (!m_scopes[&_sourceUnit]) + // By importing, it is possible that the container already exists. + m_scopes[&_sourceUnit].reset(new DeclarationContainer(nullptr, m_scopes[nullptr].get())); m_currentScope = m_scopes[&_sourceUnit].get(); // The helper registers all declarations in m_scopes as a side-effect of its construction. try { DeclarationRegistrationHelper registrar(m_scopes, _sourceUnit, m_errors); + _sourceUnit.annotation().exportedSymbols = m_scopes[&_sourceUnit]->declarations(); } catch (FatalError const&) { @@ -83,7 +85,7 @@ bool NameAndTypeResolver::performImports(SourceUnit& _sourceUnit, map<string, So ); error = true; } - else + else if (imp->name().empty()) { auto scope = m_scopes.find(_sourceUnits.at(path)); solAssert(scope != end(m_scopes), ""); @@ -380,7 +382,7 @@ void NameAndTypeResolver::reportFatalTypeError(Error const& _e) } DeclarationRegistrationHelper::DeclarationRegistrationHelper( - map<ASTNode const*, unique_ptr<DeclarationContainer>>& _scopes, + map<ASTNode const*, shared_ptr<DeclarationContainer>>& _scopes, ASTNode& _astRoot, ErrorList& _errors ): @@ -392,6 +394,17 @@ DeclarationRegistrationHelper::DeclarationRegistrationHelper( _astRoot.accept(*this); } +bool DeclarationRegistrationHelper::visit(ImportDirective& _import) +{ + SourceUnit const* importee = _import.annotation().sourceUnit; + solAssert(!!importee, ""); + if (!m_scopes[importee]) + m_scopes[importee].reset(new DeclarationContainer(nullptr, m_scopes[nullptr].get())); + m_scopes[&_import] = m_scopes[importee]; + registerDeclaration(_import, false); + return true; +} + bool DeclarationRegistrationHelper::visit(ContractDefinition& _contract) { registerDeclaration(_contract, true); @@ -489,9 +502,9 @@ void DeclarationRegistrationHelper::endVisit(EventDefinition&) void DeclarationRegistrationHelper::enterNewSubScope(Declaration const& _declaration) { - map<ASTNode const*, unique_ptr<DeclarationContainer>>::iterator iter; + map<ASTNode const*, shared_ptr<DeclarationContainer>>::iterator iter; bool newlyAdded; - unique_ptr<DeclarationContainer> container(new DeclarationContainer(m_currentScope, m_scopes[m_currentScope].get())); + shared_ptr<DeclarationContainer> container(new DeclarationContainer(m_currentScope, m_scopes[m_currentScope].get())); tie(iter, newlyAdded) = m_scopes.emplace(&_declaration, move(container)); solAssert(newlyAdded, "Unable to add new scope."); m_currentScope = &_declaration; diff --git a/libsolidity/analysis/NameAndTypeResolver.h b/libsolidity/analysis/NameAndTypeResolver.h index 3c444aba..89b9818b 100644 --- a/libsolidity/analysis/NameAndTypeResolver.h +++ b/libsolidity/analysis/NameAndTypeResolver.h @@ -111,7 +111,8 @@ private: /// Maps nodes declaring a scope to scopes, i.e. ContractDefinition and FunctionDeclaration, /// where nullptr denotes the global scope. Note that structs are not scope since they do /// not contain code. - std::map<ASTNode const*, std::unique_ptr<DeclarationContainer>> m_scopes; + /// Aliases (for example `import "x" as y;`) create multiple pointers to the same scope. + std::map<ASTNode const*, std::shared_ptr<DeclarationContainer>> m_scopes; DeclarationContainer* m_currentScope = nullptr; ErrorList& m_errors; @@ -125,12 +126,13 @@ class DeclarationRegistrationHelper: private ASTVisitor { public: DeclarationRegistrationHelper( - std::map<ASTNode const*, std::unique_ptr<DeclarationContainer>>& _scopes, + std::map<ASTNode const*, std::shared_ptr<DeclarationContainer>>& _scopes, ASTNode& _astRoot, ErrorList& _errors ); private: + bool visit(ImportDirective& _declaration) override; bool visit(ContractDefinition& _contract) override; void endVisit(ContractDefinition& _contract) override; bool visit(StructDefinition& _struct) override; @@ -166,7 +168,7 @@ private: // creates the Declaration error and adds it in the errors list and throws FatalError void fatalDeclarationError(SourceLocation _sourceLocation, std::string const& _description); - std::map<ASTNode const*, std::unique_ptr<DeclarationContainer>>& m_scopes; + std::map<ASTNode const*, std::shared_ptr<DeclarationContainer>>& m_scopes; ASTNode const* m_currentScope = nullptr; VariableScope* m_currentFunction = nullptr; ErrorList& m_errors; |