mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Blocks and for loops can be scopes.
This commit is contained in:
parent
5f20129e65
commit
e6d48bb72a
@ -610,6 +610,30 @@ void DeclarationRegistrationHelper::endVisit(ModifierDefinition&)
|
|||||||
closeCurrentScope();
|
closeCurrentScope();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DeclarationRegistrationHelper::visit(Block& _block)
|
||||||
|
{
|
||||||
|
enterNewSubScope(_block);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeclarationRegistrationHelper::endVisit(Block&)
|
||||||
|
{
|
||||||
|
closeCurrentScope();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeclarationRegistrationHelper::visit(ForStatement& _for)
|
||||||
|
{
|
||||||
|
// TODO special scoping rules for the init statement - if it is a block, then it should
|
||||||
|
// not open its own scope.
|
||||||
|
enterNewSubScope(_for);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeclarationRegistrationHelper::endVisit(ForStatement&)
|
||||||
|
{
|
||||||
|
closeCurrentScope();
|
||||||
|
}
|
||||||
|
|
||||||
void DeclarationRegistrationHelper::endVisit(VariableDeclarationStatement& _variableDeclarationStatement)
|
void DeclarationRegistrationHelper::endVisit(VariableDeclarationStatement& _variableDeclarationStatement)
|
||||||
{
|
{
|
||||||
// Register the local variables with the function
|
// Register the local variables with the function
|
||||||
|
@ -167,6 +167,10 @@ private:
|
|||||||
void endVisit(FunctionDefinition& _function) override;
|
void endVisit(FunctionDefinition& _function) override;
|
||||||
bool visit(ModifierDefinition& _modifier) override;
|
bool visit(ModifierDefinition& _modifier) override;
|
||||||
void endVisit(ModifierDefinition& _modifier) override;
|
void endVisit(ModifierDefinition& _modifier) override;
|
||||||
|
bool visit(Block& _block) override;
|
||||||
|
void endVisit(Block& _block) override;
|
||||||
|
bool visit(ForStatement& _forLoop) override;
|
||||||
|
void endVisit(ForStatement& _forLoop) override;
|
||||||
void endVisit(VariableDeclarationStatement& _variableDeclarationStatement) override;
|
void endVisit(VariableDeclarationStatement& _variableDeclarationStatement) override;
|
||||||
bool visit(VariableDeclaration& _declaration) override;
|
bool visit(VariableDeclaration& _declaration) override;
|
||||||
bool visit(EventDefinition& _event) override;
|
bool visit(EventDefinition& _event) override;
|
||||||
|
@ -43,6 +43,37 @@ bool ReferencesResolver::resolve(ASTNode const& _root)
|
|||||||
return !m_errorOccurred;
|
return !m_errorOccurred;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ReferencesResolver::visit(Block const& _block)
|
||||||
|
{
|
||||||
|
if (!m_resolveInsideCode)
|
||||||
|
return false;
|
||||||
|
m_resolver.setScope(&_block);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReferencesResolver::endVisit(Block const& _block)
|
||||||
|
{
|
||||||
|
if (!m_resolveInsideCode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_resolver.setScope(_block.scope());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReferencesResolver::visit(ForStatement const& _for)
|
||||||
|
{
|
||||||
|
if (!m_resolveInsideCode)
|
||||||
|
return false;
|
||||||
|
m_resolver.setScope(&_for);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReferencesResolver::endVisit(ForStatement const& _for)
|
||||||
|
{
|
||||||
|
if (!m_resolveInsideCode)
|
||||||
|
return;
|
||||||
|
m_resolver.setScope(_for.scope());
|
||||||
|
}
|
||||||
|
|
||||||
bool ReferencesResolver::visit(Identifier const& _identifier)
|
bool ReferencesResolver::visit(Identifier const& _identifier)
|
||||||
{
|
{
|
||||||
auto declarations = m_resolver.nameFromCurrentScope(_identifier.name());
|
auto declarations = m_resolver.nameFromCurrentScope(_identifier.name());
|
||||||
|
@ -57,7 +57,10 @@ public:
|
|||||||
bool resolve(ASTNode const& _root);
|
bool resolve(ASTNode const& _root);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool visit(Block const&) override { return m_resolveInsideCode; }
|
virtual bool visit(Block const& _block) override;
|
||||||
|
virtual void endVisit(Block const& _block) override;
|
||||||
|
virtual bool visit(ForStatement const& _for) override;
|
||||||
|
virtual void endVisit(ForStatement const& _for) override;
|
||||||
virtual bool visit(Identifier const& _identifier) override;
|
virtual bool visit(Identifier const& _identifier) override;
|
||||||
virtual bool visit(ElementaryTypeName const& _typeName) override;
|
virtual bool visit(ElementaryTypeName const& _typeName) override;
|
||||||
virtual bool visit(FunctionDefinition const& _functionDefinition) override;
|
virtual bool visit(FunctionDefinition const& _functionDefinition) override;
|
||||||
|
@ -415,6 +415,15 @@ bool VariableDeclaration::isLValue() const
|
|||||||
return !isExternalCallableParameter() && !m_isConstant;
|
return !isExternalCallableParameter() && !m_isConstant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VariableDeclaration::isLocalVariable() const
|
||||||
|
{
|
||||||
|
auto s = scope();
|
||||||
|
return
|
||||||
|
dynamic_cast<CallableDeclaration const*>(s) ||
|
||||||
|
dynamic_cast<Block const*>(s) ||
|
||||||
|
dynamic_cast<ForStatement const*>(s);
|
||||||
|
}
|
||||||
|
|
||||||
bool VariableDeclaration::isCallableParameter() const
|
bool VariableDeclaration::isCallableParameter() const
|
||||||
{
|
{
|
||||||
auto const* callable = dynamic_cast<CallableDeclaration const*>(scope());
|
auto const* callable = dynamic_cast<CallableDeclaration const*>(scope());
|
||||||
@ -460,8 +469,7 @@ bool VariableDeclaration::isExternalCallableParameter() const
|
|||||||
|
|
||||||
bool VariableDeclaration::canHaveAutoType() const
|
bool VariableDeclaration::canHaveAutoType() const
|
||||||
{
|
{
|
||||||
auto const* callable = dynamic_cast<CallableDeclaration const*>(scope());
|
return isLocalVariable() && !isCallableParameter();
|
||||||
return (!!callable && !isCallableParameter());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer VariableDeclaration::type() const
|
TypePointer VariableDeclaration::type() const
|
||||||
|
@ -299,6 +299,8 @@ private:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class that is added to each AST node that can store local variables.
|
* Abstract class that is added to each AST node that can store local variables.
|
||||||
|
* Local variables in functions are always added to functions, even though they are not
|
||||||
|
* in scope for the whole function.
|
||||||
*/
|
*/
|
||||||
class VariableScope
|
class VariableScope
|
||||||
{
|
{
|
||||||
@ -672,7 +674,7 @@ public:
|
|||||||
virtual bool isLValue() const override;
|
virtual bool isLValue() const override;
|
||||||
virtual bool isPartOfExternalInterface() const override { return isPublic(); }
|
virtual bool isPartOfExternalInterface() const override { return isPublic(); }
|
||||||
|
|
||||||
bool isLocalVariable() const { return !!dynamic_cast<CallableDeclaration const*>(scope()); }
|
bool isLocalVariable() const;
|
||||||
/// @returns true if this variable is a parameter or return parameter of a function.
|
/// @returns true if this variable is a parameter or return parameter of a function.
|
||||||
bool isCallableParameter() const;
|
bool isCallableParameter() const;
|
||||||
/// @returns true if this variable is a return parameter of a function.
|
/// @returns true if this variable is a return parameter of a function.
|
||||||
@ -1014,7 +1016,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Brace-enclosed block containing zero or more statements.
|
* Brace-enclosed block containing zero or more statements.
|
||||||
*/
|
*/
|
||||||
class Block: public Statement
|
class Block: public Statement, public Scopable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Block(
|
Block(
|
||||||
@ -1121,7 +1123,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* For loop statement
|
* For loop statement
|
||||||
*/
|
*/
|
||||||
class ForStatement: public BreakableStatement
|
class ForStatement: public BreakableStatement, public Scopable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ForStatement(
|
ForStatement(
|
||||||
|
Loading…
Reference in New Issue
Block a user