Assign scopes as a separate step.

This commit is contained in:
chriseth
2020-09-02 20:45:33 +02:00
parent 767d06b297
commit 2934a1f037
10 changed files with 147 additions and 18 deletions
+5 -5
View File
@@ -607,7 +607,7 @@ void DeclarationRegistrationHelper::endVisit(FunctionDefinition&)
bool DeclarationRegistrationHelper::visit(TryCatchClause& _tryCatchClause)
{
_tryCatchClause.annotation().scope = m_currentScope;
solAssert(_tryCatchClause.annotation().scope == m_currentScope, "");
enterNewSubScope(_tryCatchClause);
return true;
}
@@ -643,7 +643,7 @@ void DeclarationRegistrationHelper::endVisit(FunctionTypeName&)
bool DeclarationRegistrationHelper::visit(Block& _block)
{
_block.annotation().scope = m_currentScope;
solAssert(_block.annotation().scope == m_currentScope, "");
enterNewSubScope(_block);
return true;
}
@@ -655,7 +655,7 @@ void DeclarationRegistrationHelper::endVisit(Block&)
bool DeclarationRegistrationHelper::visit(ForStatement& _for)
{
_for.annotation().scope = m_currentScope;
solAssert(_for.annotation().scope == m_currentScope, "");
enterNewSubScope(_for);
return true;
}
@@ -729,8 +729,8 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio
registerDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, warnAboutShadowing, inactive, m_errorReporter);
_declaration.annotation().scope = m_currentScope;
_declaration.annotation().contract = m_currentContract;
solAssert(_declaration.annotation().scope == m_currentScope, "");
solAssert(_declaration.annotation().contract == m_currentContract, "");
if (_opensScope)
enterNewSubScope(_declaration);
}
+63
View File
@@ -0,0 +1,63 @@
/*
This file is part of solidity.
solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
#include <libsolidity/analysis/Scoper.h>
#include <libsolidity/ast/AST.h>
using namespace std;
using namespace solidity;
using namespace solidity::frontend;
void Scoper::assignScopes(ASTNode const& _astRoot)
{
Scoper scoper;
_astRoot.accept(scoper);
}
bool Scoper::visit(ContractDefinition const& _contract)
{
solAssert(m_contract == nullptr, "");
m_contract = &_contract;
return ASTConstVisitor::visit(_contract);
}
void Scoper::endVisit(ContractDefinition const& _contract)
{
solAssert(m_contract == &_contract, "");
m_contract = nullptr;
ASTConstVisitor::endVisit(_contract);
}
bool Scoper::visitNode(ASTNode const& _node)
{
if (auto const* scopable = dynamic_cast<Scopable const*>(&_node))
{
scopable->annotation().scope = m_scopes.empty() ? nullptr : m_scopes.back();
scopable->annotation().contract = m_contract;
}
if (dynamic_cast<ScopeOpener const*>(&_node))
m_scopes.push_back(&_node);
return true;
}
void Scoper::endVisitNode(ASTNode const& _node)
{
if (dynamic_cast<ScopeOpener const*>(&_node))
m_scopes.pop_back();
}
+45
View File
@@ -0,0 +1,45 @@
/*
This file is part of solidity.
solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
#pragma once
#include <libsolidity/ast/ASTForward.h>
#include <libsolidity/ast/ASTVisitor.h>
namespace solidity::frontend
{
/**
* AST visitor that assigns syntactic scopes.
*/
class Scoper: private ASTConstVisitor
{
public:
static void assignScopes(ASTNode const& _astRoot);
private:
bool visit(ContractDefinition const& _contract) override;
void endVisit(ContractDefinition const& _contract) override;
bool visitNode(ASTNode const& _node) override;
void endVisitNode(ASTNode const& _node) override;
ContractDefinition const* m_contract = nullptr;
std::vector<ASTNode const*> m_scopes;
};
}