mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Enable C99-scoping with the 0.5.0-experimental pragma.
This commit is contained in:
parent
e227bdbfa7
commit
6b9dda06f3
@ -612,26 +612,34 @@ void DeclarationRegistrationHelper::endVisit(ModifierDefinition&)
|
||||
|
||||
bool DeclarationRegistrationHelper::visit(Block& _block)
|
||||
{
|
||||
enterNewSubScope(_block);
|
||||
_block.setScope(m_currentScope);
|
||||
// Enable C99-scoped variables.
|
||||
if (_block.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050))
|
||||
enterNewSubScope(_block);
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeclarationRegistrationHelper::endVisit(Block&)
|
||||
void DeclarationRegistrationHelper::endVisit(Block& _block)
|
||||
{
|
||||
closeCurrentScope();
|
||||
// Enable C99-scoped variables.
|
||||
if (_block.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050))
|
||||
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);
|
||||
_for.setScope(m_currentScope);
|
||||
if (_for.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050))
|
||||
// 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&)
|
||||
void DeclarationRegistrationHelper::endVisit(ForStatement& _for)
|
||||
{
|
||||
closeCurrentScope();
|
||||
if (_for.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050))
|
||||
closeCurrentScope();
|
||||
}
|
||||
|
||||
void DeclarationRegistrationHelper::endVisit(VariableDeclarationStatement& _variableDeclarationStatement)
|
||||
@ -663,9 +671,6 @@ void DeclarationRegistrationHelper::endVisit(EventDefinition&)
|
||||
|
||||
void DeclarationRegistrationHelper::enterNewSubScope(ASTNode& _subScope)
|
||||
{
|
||||
if (auto s = dynamic_cast<Scopable*>(&_subScope))
|
||||
s->setScope(m_currentScope);
|
||||
|
||||
map<ASTNode const*, shared_ptr<DeclarationContainer>>::iterator iter;
|
||||
bool newlyAdded;
|
||||
shared_ptr<DeclarationContainer> container(new DeclarationContainer(m_currentScope, m_scopes[m_currentScope].get()));
|
||||
@ -701,10 +706,9 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio
|
||||
|
||||
registerDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, warnAboutShadowing, m_errorReporter);
|
||||
|
||||
_declaration.setScope(m_currentScope);
|
||||
if (_opensScope)
|
||||
enterNewSubScope(_declaration);
|
||||
else
|
||||
_declaration.setScope(m_currentScope);
|
||||
}
|
||||
|
||||
string DeclarationRegistrationHelper::currentCanonicalName() const
|
||||
|
@ -47,7 +47,10 @@ bool ReferencesResolver::visit(Block const& _block)
|
||||
{
|
||||
if (!m_resolveInsideCode)
|
||||
return false;
|
||||
m_resolver.setScope(&_block);
|
||||
m_experimental050Mode = _block.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
|
||||
// C99-scoped variables
|
||||
if (m_experimental050Mode)
|
||||
m_resolver.setScope(&_block);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -56,14 +59,19 @@ void ReferencesResolver::endVisit(Block const& _block)
|
||||
if (!m_resolveInsideCode)
|
||||
return;
|
||||
|
||||
m_resolver.setScope(_block.scope());
|
||||
// C99-scoped variables
|
||||
if (m_experimental050Mode)
|
||||
m_resolver.setScope(_block.scope());
|
||||
}
|
||||
|
||||
bool ReferencesResolver::visit(ForStatement const& _for)
|
||||
{
|
||||
if (!m_resolveInsideCode)
|
||||
return false;
|
||||
m_resolver.setScope(&_for);
|
||||
m_experimental050Mode = _for.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
|
||||
// C99-scoped variables
|
||||
if (m_experimental050Mode)
|
||||
m_resolver.setScope(&_for);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -71,7 +79,8 @@ void ReferencesResolver::endVisit(ForStatement const& _for)
|
||||
{
|
||||
if (!m_resolveInsideCode)
|
||||
return;
|
||||
m_resolver.setScope(_for.scope());
|
||||
if (m_experimental050Mode)
|
||||
m_resolver.setScope(_for.scope());
|
||||
}
|
||||
|
||||
bool ReferencesResolver::visit(Identifier const& _identifier)
|
||||
|
@ -93,6 +93,7 @@ private:
|
||||
std::vector<ParameterList const*> m_returnParameters;
|
||||
bool const m_resolveInsideCode;
|
||||
bool m_errorOccurred = false;
|
||||
bool m_experimental050Mode = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -96,21 +96,6 @@ set<SourceUnit const*> SourceUnit::referencedSourceUnits(bool _recurse, set<Sour
|
||||
return sourceUnits;
|
||||
}
|
||||
|
||||
SourceUnit const& Declaration::sourceUnit() const
|
||||
{
|
||||
ASTNode const* s = scope();
|
||||
solAssert(s, "");
|
||||
// will not always be a declaratoion
|
||||
while (dynamic_cast<Scopable const*>(s) && dynamic_cast<Scopable const*>(s)->scope())
|
||||
s = dynamic_cast<Scopable const*>(s)->scope();
|
||||
return dynamic_cast<SourceUnit const&>(*s);
|
||||
}
|
||||
|
||||
string Declaration::sourceUnitName() const
|
||||
{
|
||||
return sourceUnit().annotation().path;
|
||||
}
|
||||
|
||||
ImportAnnotation& ImportDirective::annotation() const
|
||||
{
|
||||
if (!m_annotation)
|
||||
@ -409,6 +394,21 @@ UserDefinedTypeNameAnnotation& UserDefinedTypeName::annotation() const
|
||||
return dynamic_cast<UserDefinedTypeNameAnnotation&>(*m_annotation);
|
||||
}
|
||||
|
||||
SourceUnit const& Scopable::sourceUnit() const
|
||||
{
|
||||
ASTNode const* s = scope();
|
||||
solAssert(s, "");
|
||||
// will not always be a declaratoion
|
||||
while (dynamic_cast<Scopable const*>(s) && dynamic_cast<Scopable const*>(s)->scope())
|
||||
s = dynamic_cast<Scopable const*>(s)->scope();
|
||||
return dynamic_cast<SourceUnit const&>(*s);
|
||||
}
|
||||
|
||||
string Scopable::sourceUnitName() const
|
||||
{
|
||||
return sourceUnit().annotation().path;
|
||||
}
|
||||
|
||||
bool VariableDeclaration::isLValue() const
|
||||
{
|
||||
// External function parameters and constant declared variables are Read-Only
|
||||
|
@ -151,6 +151,13 @@ public:
|
||||
ASTNode const* scope() const { return m_scope; }
|
||||
void setScope(ASTNode const* _scope) { m_scope = _scope; }
|
||||
|
||||
/// @returns the source unit this scopable is present in.
|
||||
SourceUnit const& sourceUnit() const;
|
||||
|
||||
/// @returns the source name this scopable is present in.
|
||||
/// Can be combined with annotation().canonicalName (if present) to form a globally unique name.
|
||||
std::string sourceUnitName() const;
|
||||
|
||||
protected:
|
||||
ASTNode const* m_scope = nullptr;
|
||||
};
|
||||
@ -197,12 +204,6 @@ public:
|
||||
virtual bool isVisibleInContract() const { return visibility() != Visibility::External; }
|
||||
bool isVisibleInDerivedContracts() const { return isVisibleInContract() && visibility() >= Visibility::Internal; }
|
||||
|
||||
/// @returns the source unit this declaration is present in.
|
||||
SourceUnit const& sourceUnit() const;
|
||||
|
||||
/// @returns the source name this declaration is present in.
|
||||
/// Can be combined with annotation().canonicalName to form a globally unique name.
|
||||
std::string sourceUnitName() const;
|
||||
std::string fullyQualifiedName() const { return sourceUnitName() + ":" + name(); }
|
||||
|
||||
virtual bool isLValue() const { return false; }
|
||||
|
@ -84,16 +84,45 @@ BOOST_AUTO_TEST_CASE(double_variable_declaration)
|
||||
}
|
||||
}
|
||||
)";
|
||||
CHECK_ERROR(text, DeclarationError, "Identifier already declared");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(double_variable_declaration_050)
|
||||
{
|
||||
string text = R"(
|
||||
pragma experimental "v0.5.0";
|
||||
contract test {
|
||||
function f() pure public {
|
||||
uint256 x;
|
||||
if (true) { uint256 x; }
|
||||
}
|
||||
}
|
||||
)";
|
||||
CHECK_WARNING_ALLOW_MULTI(text, (vector<string>{
|
||||
"This declaration shadows an existing declaration.",
|
||||
"Experimental features",
|
||||
"Unused local variable",
|
||||
"Unused local variable"
|
||||
}));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(scoping_old)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract test {
|
||||
function f() pure public {
|
||||
x = 4;
|
||||
uint256 x = 2;
|
||||
}
|
||||
}
|
||||
)";
|
||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(scoping)
|
||||
{
|
||||
char const* text = R"(
|
||||
pragma experimental "v0.5.0";
|
||||
contract test {
|
||||
function f() public {
|
||||
{
|
||||
@ -109,6 +138,7 @@ BOOST_AUTO_TEST_CASE(scoping)
|
||||
BOOST_AUTO_TEST_CASE(scoping_for)
|
||||
{
|
||||
char const* text = R"(
|
||||
pragma experimental "v0.5.0";
|
||||
contract test {
|
||||
function f() public {
|
||||
for (uint x = 0; x < 10; x ++){
|
||||
@ -123,6 +153,7 @@ BOOST_AUTO_TEST_CASE(scoping_for)
|
||||
BOOST_AUTO_TEST_CASE(scoping_for2)
|
||||
{
|
||||
char const* text = R"(
|
||||
pragma experimental "v0.5.0";
|
||||
contract test {
|
||||
function f() public {
|
||||
for (uint x = 0; x < 10; x ++){
|
||||
@ -1052,7 +1083,7 @@ BOOST_AUTO_TEST_CASE(function_modifier_invocation)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract B {
|
||||
function f() mod1(2, true) mod2("0123456") public { }
|
||||
function f() mod1(2, true) mod2("0123456") pure public { }
|
||||
modifier mod1(uint a, bool b) { if (b) _; }
|
||||
modifier mod2(bytes7 a) { while (a == "1234567") _; }
|
||||
}
|
||||
@ -1087,7 +1118,19 @@ BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables)
|
||||
{
|
||||
char const* text = R"(
|
||||
contract B {
|
||||
function f() mod(x) public { uint x = 7; }
|
||||
function f() mod(x) pure public { uint x = 7; }
|
||||
modifier mod(uint a) { if (a > 0) _; }
|
||||
}
|
||||
)";
|
||||
CHECK_SUCCESS_NO_WARNINGS(text);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables050)
|
||||
{
|
||||
char const* text = R"(
|
||||
pragma experimental "v0.5.0";
|
||||
contract B {
|
||||
function f() mod(x) pure public { uint x = 7; }
|
||||
modifier mod(uint a) { if (a > 0) _; }
|
||||
}
|
||||
)";
|
||||
|
Loading…
Reference in New Issue
Block a user