Enforces visibility specifier and updates docs.

This commit is contained in:
Erik Kundt 2018-07-04 18:04:44 +02:00
parent 1d33f41c1a
commit b5ecfbe5bc
7 changed files with 14 additions and 24 deletions

View File

@ -3,6 +3,7 @@
How to update your code: How to update your code:
* Change every ``.call()`` to a ``.call("")`` and every ``.call(signature, a, b, c)`` to use ``.call(abi.encodeWithSignature(signature, a, b, c))`` (the last one only works for value types). * Change every ``.call()`` to a ``.call("")`` and every ``.call(signature, a, b, c)`` to use ``.call(abi.encodeWithSignature(signature, a, b, c))`` (the last one only works for value types).
* Change every ``keccak256(a, b, c)`` to ``keccak256(abi.encodePacked(a, b, c))``. * Change every ``keccak256(a, b, c)`` to ``keccak256(abi.encodePacked(a, b, c))``.
* Add ``public`` to every function that does not specify its visibility already.
* Make your fallback functions ``external``. * Make your fallback functions ``external``.
* Explicitly state the storage location for local variables of struct and array types, e.g. change ``uint[] x = m_x`` to ``uint[] storage x = m_x``. * Explicitly state the storage location for local variables of struct and array types, e.g. change ``uint[] x = m_x`` to ``uint[] storage x = m_x``.
@ -49,6 +50,7 @@ Breaking Changes:
* Remove obsolete ``std`` directory from the Solidity repository. This means accessing ``https://github.com/ethereum/soldity/blob/develop/std/*.sol`` (or ``https://github.com/ethereum/solidity/std/*.sol`` in Remix) will not be possible. * Remove obsolete ``std`` directory from the Solidity repository. This means accessing ``https://github.com/ethereum/soldity/blob/develop/std/*.sol`` (or ``https://github.com/ethereum/solidity/std/*.sol`` in Remix) will not be possible.
* References Resolver: Turn missing storage locations into an error. This was already the case in the experimental 0.5.0 mode. * References Resolver: Turn missing storage locations into an error. This was already the case in the experimental 0.5.0 mode.
* Syntax Checker: Named return values in function types are an error. * Syntax Checker: Named return values in function types are an error.
* Syntax Checker: Strictly require visibility specifier. This was already the case in the experimental 0.5.0 mode.
* Syntax Checker: Disallow unary ``+``. This was already the case in the experimental 0.5.0 mode. * Syntax Checker: Disallow unary ``+``. This was already the case in the experimental 0.5.0 mode.
* View Pure Checker: Strictly enfore state mutability. This was already the case in the experimental 0.5.0 mode. * View Pure Checker: Strictly enfore state mutability. This was already the case in the experimental 0.5.0 mode.

View File

@ -131,10 +131,9 @@ a "message call") and external
ones that do), there are four types of visibilities for ones that do), there are four types of visibilities for
functions and state variables. functions and state variables.
Functions can be specified as being ``external``, Functions have to be specified as being ``external``,
``public``, ``internal`` or ``private``, where the default is ``public``, ``internal`` or ``private``.
``public``. For state variables, ``external`` is not possible For state variables, ``external`` is not possible.
and the default is ``internal``.
``external``: ``external``:
External functions are part of the contract External functions are part of the contract
@ -850,10 +849,10 @@ Details are given in the following example.
:: ::
pragma solidity ^0.4.22; pragma solidity >0.4.24;
contract owned { contract owned {
constructor() { owner = msg.sender; } constructor() public { owner = msg.sender; }
address owner; address owner;
} }
@ -862,7 +861,7 @@ Details are given in the following example.
// internal functions and state variables. These cannot be // internal functions and state variables. These cannot be
// accessed externally via `this`, though. // accessed externally via `this`, though.
contract mortal is owned { contract mortal is owned {
function kill() { function kill() public {
if (msg.sender == owner) selfdestruct(owner); if (msg.sender == owner) selfdestruct(owner);
} }
} }
@ -884,7 +883,7 @@ Details are given in the following example.
// also a base class of `mortal`, yet there is only a single // also a base class of `mortal`, yet there is only a single
// instance of `owned` (as for virtual inheritance in C++). // instance of `owned` (as for virtual inheritance in C++).
contract named is owned, mortal { contract named is owned, mortal {
constructor(bytes32 name) { constructor(bytes32 name) public {
Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970); Config config = Config(0xD5f9D8D94886E70b06E474c3fB14Fd43E2f23970);
NameReg(config.lookup(1)).register(name); NameReg(config.lookup(1)).register(name);
} }

View File

@ -465,10 +465,10 @@ The following example shows how an error string can be used together with revert
:: ::
pragma solidity ^0.4.22; pragma solidity >0.4.24;
contract VendingMachine { contract VendingMachine {
function buy(uint amount) payable { function buy(uint amount) public payable {
if (amount > msg.value / 2 ether) if (amount > msg.value / 2 ether)
revert("Not enough Ether provided."); revert("Not enough Ether provided.");
// Alternative way to do it: // Alternative way to do it:

View File

@ -205,7 +205,7 @@ for the two input parameters and two returned values.
* @return s The calculated surface. * @return s The calculated surface.
* @return p The calculated perimeter. * @return p The calculated perimeter.
*/ */
function rectangle(uint w, uint h) returns (uint s, uint p) { function rectangle(uint w, uint h) public returns (uint s, uint p) {
s = w * h; s = w * h;
p = 2 * (w + h); p = 2 * (w + h);
} }

View File

@ -483,7 +483,7 @@ Another example that uses external function types::
contract OracleUser { contract OracleUser {
Oracle constant oracle = Oracle(0x1234567); // known contract Oracle constant oracle = Oracle(0x1234567); // known contract
function buySomething() { function buySomething() public {
oracle.query("USD", this.oracleResponse); oracle.query("USD", this.oracleResponse);
} }
function oracleResponse(bytes memory response) public { function oracleResponse(bytes memory response) public {
@ -979,4 +979,3 @@ converted to a matching size. This makes alignment and padding explicit::
uint16 x = 0xffff; uint16 x = 0xffff;
bytes32(uint256(x)); // pad on the left bytes32(uint256(x)); // pad on the left
bytes32(bytes2(x)); // pad on the right bytes32(bytes2(x)); // pad on the right

View File

@ -51,16 +51,6 @@ void StaticAnalyzer::endVisit(ContractDefinition const&)
bool StaticAnalyzer::visit(FunctionDefinition const& _function) bool StaticAnalyzer::visit(FunctionDefinition const& _function)
{ {
const bool isInterface = m_currentContract->contractKind() == ContractDefinition::ContractKind::Interface;
if (_function.noVisibilitySpecified())
m_errorReporter.warning(
_function.location(),
"No visibility specified. Defaulting to \"" +
Declaration::visibilityToString(_function.visibility()) +
"\"." +
(isInterface ? " In interfaces it defaults to external." : "")
);
if (_function.isImplemented()) if (_function.isImplemented())
m_currentFunction = &_function; m_currentFunction = &_function;
else else

View File

@ -201,7 +201,7 @@ bool SyntaxChecker::visit(FunctionDefinition const& _function)
{ {
bool const v050 = m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeature::V050); bool const v050 = m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeature::V050);
if (v050 && _function.noVisibilitySpecified()) if (_function.noVisibilitySpecified())
m_errorReporter.syntaxError(_function.location(), "No visibility specified."); m_errorReporter.syntaxError(_function.location(), "No visibility specified.");
if (_function.isOldStyleConstructor()) if (_function.isOldStyleConstructor())