Conversation
8dc5a06 to
df89722
Compare
|
Sorry I forgot to assign the issue to myself, but did mention the last call I started this work. Anyway it is not a big amount of duplicate effort :) However we should only merge this after #4208 |
|
@axic Oh sorry, did not get this in the last call. We should try to keep the project board up to date ;) I agree, let's merge the other PR first. |
|
@bit-shift I will have a look at the differences between the two PRs. Do you want to review #4208 ? |
|
My local version of these changes are all included int this PR. |
870a0eb to
ee59eec
Compare
|
@christianparpart I removed the expected shadowing warning of |
chriseth
left a comment
There was a problem hiding this comment.
Is there a test for
contract C {
function constructor() { ... }
}?
| bool SyntaxChecker::visit(ContractDefinition const& _contract) | ||
| { | ||
| ASTString const& contractName = _contract.name(); | ||
| for (const FunctionDefinition* const function : _contract.definedFunctions()) |
There was a problem hiding this comment.
Should be FunctionDefinition const* const function, but I think the last const does not really help readability and thus could be dropped.
| for (const FunctionDefinition* const function : _contract.definedFunctions()) | ||
| if (function->name() == contractName) | ||
| m_errorReporter.syntaxError(function->location(), | ||
| "Defining constructors as functions with the same name as the contract is not allowed. " |
There was a problem hiding this comment.
Please use the original v050 message and not the message of the pre-050 warning. Also, the indentation and line breaks are not according to coding style.
| m_errorReporter.warning(_function.location(), "Modifiers of functions without implementation are ignored." ); | ||
| } | ||
| if (_function.name() == "constructor") | ||
| if (_function.name() == "constructor" && !_function.isConstructor()) |
There was a problem hiding this comment.
Please don't add !_function.isConstructor(). Currently, it looks like this is a good thing to add, but it might hide errors that are introduced when we change the logic of isConstructor.
libsolidity/parsing/Parser.cpp
Outdated
|
|
||
| if (result.isConstructor || _forceEmptyName || m_scanner->currentToken() == Token::LParen) | ||
| if (result.isConstructor) | ||
| result.name = make_shared<ASTString>("constructor"); |
There was a problem hiding this comment.
I think the name should still be empty.
libsolidity/parsing/Parser.cpp
Outdated
| result.name = make_shared<ASTString>("constructor"); | ||
| else if (_forceEmptyName || m_scanner->currentToken() == Token::LParen) | ||
| result.name = make_shared<ASTString>(); | ||
| else if (m_scanner->currentToken() == Token::Constructor && !result.isConstructor) |
There was a problem hiding this comment.
Is this to still allow function constructor(...) { ..}? I don't think we have to support that - constructor is now a real keyword and thus functions cannot be named constructor.
There was a problem hiding this comment.
Yes, the idea was to still allow it, but warn about it's usage. But you're right, since this is keyword now, we should not allow it anymore.
There was a problem hiding this comment.
!result.isConstructor can be removed (it is an else if).
| // It is fine to "override" constructor of a base class since it is invisible | ||
| contract A { function A() public { } } | ||
| contract A { constructor() public {} } | ||
| contract B is A { function A() public pure returns (uint8) {} } |
There was a problem hiding this comment.
Yep, that is exactly what we should test here!
| function Main() payable { | ||
| h = (new Helper).value(10)("abc", true); | ||
| constructor() payable { | ||
| h = (new Helper).value(10)('abc', true); |
There was a problem hiding this comment.
Any reason for this change?
There was a problem hiding this comment.
Oh, this was an unconscious change due to broken code highlighting in my editor. We can revert to "abc"
test/libsolidity/SolidityParser.cpp
Outdated
| "after", | ||
| "case", | ||
| "catch", | ||
| "constructor" |
There was a problem hiding this comment.
constructor should not be reserved, it should be a keyword "in use".
10a63bb to
ef49d2c
Compare
|
Depends on #4206. |
|
This could be fixed without the external tests: Also syntax test expectations need to be updated. |
libsolidity/parsing/Parser.cpp
Outdated
| result.name = make_shared<ASTString>(); | ||
| else if (_forceEmptyName || m_scanner->currentToken() == Token::LParen) | ||
| result.name = make_shared<ASTString>(); | ||
| else if (m_scanner->currentToken() == Token::Constructor && !result.isConstructor) |
There was a problem hiding this comment.
I don't think this can happen since expectIdentifierToken shouldn't allow a non-identifier, such as Token::Constructor. Is there a test for this which needs this extra condition here?
There was a problem hiding this comment.
@axic This check should have been removed already. Thanks!
|
@axic I updated the broken ABI tests. |
|
@chriseth The file
|
df180f5 to
024e897
Compare
|
Please rebase to trigger the tests. |
91ad649 to
b4aaa30
Compare
|
Tests are failing. |
|
We need to merge #4354 first. After merging, this PR needs to be updated such that it removes the old syntax tests that expect a warning instead of an error. |
85ca746 to
5b3e08b
Compare
|
Updated this PR again after #4354 got merged. Should be ready for final review now. |
|
I missed the docs here, but will add these changes. |
96d449c to
bc5f671
Compare
|
I've split out the required changes to the documentation: #4402. After that PR got merged, we can merge this one. |
bc5f671 to
7510875
Compare
| dynamic_cast<FunctionDefinition const*>(&_declaration) && | ||
| name == decl->name()) | ||
| ) | ||
| shadowedDeclaration = decl; |
There was a problem hiding this comment.
So only something that is a function can be shadowed by something that's not a contract with the same name?
What about contract C { uint msg; }? Currently this warns: This declaration shadows a builtin symbol.. And I think this comes from below in this function (I may be wrong) - does that still work? Is there a test for it?
There was a problem hiding this comment.
We have a test for the case you've mentioned: 452_shadowing_builtins_with_storage_variables.sol
There was a problem hiding this comment.
After we talked about that: I've improved the formatting to make the condition easier to understand 😄
| @@ -476,7 +476,15 @@ bool DeclarationRegistrationHelper::registerDeclaration( | |||
| Declaration const* shadowedDeclaration = nullptr; | |||
| if (_warnOnShadow && !name.empty() && _container.enclosingContainer()) | |||
| for (auto const* decl: _container.enclosingContainer()->resolveName(name, true, true)) | |||
There was a problem hiding this comment.
Unrelated to this PR, but why do we have a for loop here?
| if (_warnOnShadow && !name.empty() && _container.enclosingContainer()) | ||
| for (auto const* decl: _container.enclosingContainer()->resolveName(name, true, true)) | ||
| shadowedDeclaration = decl; | ||
| // Do not warn about functions shadowing a contract. |
There was a problem hiding this comment.
Can you explain the reason for this?
There was a problem hiding this comment.
@chriseth Without this change, the following code would result in a warning about function A() shadowing contract A:
contract A { constructor() public {} }
contract B is A { function A() public pure returns (uint8) {} }
Since functions can now have the same name as a previously declared contract, this should not warn. We also have a test for that: overriding_constructor.sol.
There was a problem hiding this comment.
I would say the warning is correct, since it does shadow A. Note the following does not work because the function A shadows the contract A:
contract A { function f() public {} }
contract B is A {
function A() public pure returns (uint8) {}
function g() public {
A.f();
}
}
| bool SyntaxChecker::visit(ContractDefinition const& _contract) | ||
| { | ||
| ASTString const& contractName = _contract.name(); | ||
| for (FunctionDefinition const* function : _contract.definedFunctions()) |
015c823 to
2c01950
Compare
|
Rebased and squashed some commits. @chriseth I've also addressed your comment about a function shadowing a contract: #4215 (comment). |
| @@ -0,0 +1,9 @@ | |||
| contract A { | |||
There was a problem hiding this comment.
Please move the positive case into its own test.
2c01950 to
b0b35e1
Compare
|
@chriseth I reverted merging both, the new and the old constructor syntax, into one file. I also rebased the branch. |
Closes #4106.