mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #4788 from ethereum/noWarnDoc
Test that documentation does not contain any warnings.
This commit is contained in:
commit
414559bd07
@ -494,8 +494,8 @@ As an example, the code
|
|||||||
contract Test {
|
contract Test {
|
||||||
struct S { uint a; uint[] b; T[] c; }
|
struct S { uint a; uint[] b; T[] c; }
|
||||||
struct T { uint x; uint y; }
|
struct T { uint x; uint y; }
|
||||||
function f(S memory s, T memory t, uint a) public { }
|
function f(S memory s, T memory t, uint a) public;
|
||||||
function g() public returns (S memory s, T memory t, uint a) {}
|
function g() public returns (S memory s, T memory t, uint a);
|
||||||
}
|
}
|
||||||
|
|
||||||
would result in the JSON:
|
would result in the JSON:
|
||||||
|
@ -82,7 +82,7 @@ you really know what you are doing.
|
|||||||
library VectorSum {
|
library VectorSum {
|
||||||
// This function is less efficient because the optimizer currently fails to
|
// This function is less efficient because the optimizer currently fails to
|
||||||
// remove the bounds checks in array access.
|
// remove the bounds checks in array access.
|
||||||
function sumSolidity(uint[] memory _data) public view returns (uint o_sum) {
|
function sumSolidity(uint[] memory _data) public pure returns (uint o_sum) {
|
||||||
for (uint i = 0; i < _data.length; ++i)
|
for (uint i = 0; i < _data.length; ++i)
|
||||||
o_sum += _data[i];
|
o_sum += _data[i];
|
||||||
}
|
}
|
||||||
@ -90,7 +90,7 @@ you really know what you are doing.
|
|||||||
// We know that we only access the array in bounds, so we can avoid the check.
|
// We know that we only access the array in bounds, so we can avoid the check.
|
||||||
// 0x20 needs to be added to an array because the first slot contains the
|
// 0x20 needs to be added to an array because the first slot contains the
|
||||||
// array length.
|
// array length.
|
||||||
function sumAsm(uint[] memory _data) public view returns (uint o_sum) {
|
function sumAsm(uint[] memory _data) public pure returns (uint o_sum) {
|
||||||
for (uint i = 0; i < _data.length; ++i) {
|
for (uint i = 0; i < _data.length; ++i) {
|
||||||
assembly {
|
assembly {
|
||||||
o_sum := add(o_sum, mload(add(add(_data, 0x20), mul(i, 0x20))))
|
o_sum := add(o_sum, mload(add(add(_data, 0x20), mul(i, 0x20))))
|
||||||
@ -99,7 +99,7 @@ you really know what you are doing.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Same as above, but accomplish the entire code within inline assembly.
|
// Same as above, but accomplish the entire code within inline assembly.
|
||||||
function sumPureAsm(uint[] memory _data) public view returns (uint o_sum) {
|
function sumPureAsm(uint[] memory _data) public pure returns (uint o_sum) {
|
||||||
assembly {
|
assembly {
|
||||||
// Load the length (first 32 bytes)
|
// Load the length (first 32 bytes)
|
||||||
let len := mload(_data)
|
let len := mload(_data)
|
||||||
@ -378,23 +378,13 @@ used ``x_slot`` and to retrieve the byte-offset you used ``x_offset``.
|
|||||||
|
|
||||||
In assignments (see below), we can even use local Solidity variables to assign to.
|
In assignments (see below), we can even use local Solidity variables to assign to.
|
||||||
|
|
||||||
Functions external to inline assembly can also be accessed: The assembly will
|
|
||||||
push their entry label (with virtual function resolution applied). The calling semantics
|
|
||||||
in solidity are:
|
|
||||||
|
|
||||||
- the caller pushes ``return label``, ``arg1``, ``arg2``, ..., ``argn``
|
|
||||||
- the call returns with ``ret1``, ``ret2``, ..., ``retm``
|
|
||||||
|
|
||||||
This feature is still a bit cumbersome to use, because the stack offset essentially
|
|
||||||
changes during the call, and thus references to local variables will be wrong.
|
|
||||||
|
|
||||||
.. code::
|
.. code::
|
||||||
|
|
||||||
pragma solidity ^0.4.11;
|
pragma solidity ^0.4.11;
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
uint b;
|
uint b;
|
||||||
function f(uint x) public returns (uint r) {
|
function f(uint x) public view returns (uint r) {
|
||||||
assembly {
|
assembly {
|
||||||
r := mul(x, sload(b_slot)) // ignore the offset, we know it is zero
|
r := mul(x, sload(b_slot)) // ignore the offset, we know it is zero
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ restrictions highly readable.
|
|||||||
);
|
);
|
||||||
_;
|
_;
|
||||||
if (msg.value > _amount)
|
if (msg.value > _amount)
|
||||||
msg.sender.send(msg.value - _amount);
|
msg.sender.transfer(msg.value - _amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
function forceOwnerChange(address _newOwner)
|
function forceOwnerChange(address _newOwner)
|
||||||
|
@ -110,11 +110,11 @@ This means that cyclic creation dependencies are impossible.
|
|||||||
|
|
||||||
function isTokenTransferOK(address currentOwner, address newOwner)
|
function isTokenTransferOK(address currentOwner, address newOwner)
|
||||||
public
|
public
|
||||||
view
|
pure
|
||||||
returns (bool ok)
|
returns (bool ok)
|
||||||
{
|
{
|
||||||
// Check some arbitrary condition.
|
// Check some arbitrary condition.
|
||||||
return currentOwner != newOwner;
|
return keccak256(abi.encodePacked(currentOwner, newOwner))[0] == 0x7f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,16 +137,16 @@ Functions have to be specified as being ``external``,
|
|||||||
For state variables, ``external`` is not possible.
|
For state variables, ``external`` is not possible.
|
||||||
|
|
||||||
``external``:
|
``external``:
|
||||||
External functions are part of the contract
|
External functions are part of the contract interface,
|
||||||
interface, which means they can be called from other contracts and
|
which means they can be called from other contracts and
|
||||||
via transactions. An external function ``f`` cannot be called
|
via transactions. An external function ``f`` cannot be called
|
||||||
internally (i.e. ``f()`` does not work, but ``this.f()`` works).
|
internally (i.e. ``f()`` does not work, but ``this.f()`` works).
|
||||||
External functions are sometimes more efficient when
|
External functions are sometimes more efficient when
|
||||||
they receive large arrays of data.
|
they receive large arrays of data.
|
||||||
|
|
||||||
``public``:
|
``public``:
|
||||||
Public functions are part of the contract
|
Public functions are part of the contract interface
|
||||||
interface and can be either called internally or via
|
and can be either called internally or via
|
||||||
messages. For public state variables, an automatic getter
|
messages. For public state variables, an automatic getter
|
||||||
function (see below) is generated.
|
function (see below) is generated.
|
||||||
|
|
||||||
@ -187,8 +187,6 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
// This will not compile
|
|
||||||
|
|
||||||
pragma solidity ^0.4.0;
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
@ -200,6 +198,7 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value
|
|||||||
function compute(uint a, uint b) internal pure returns (uint) { return a + b; }
|
function compute(uint a, uint b) internal pure returns (uint) { return a + b; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This will not compile
|
||||||
contract D {
|
contract D {
|
||||||
function readData() public {
|
function readData() public {
|
||||||
C c = new C();
|
C c = new C();
|
||||||
@ -227,8 +226,8 @@ The compiler automatically creates getter functions for
|
|||||||
all **public** state variables. For the contract given below, the compiler will
|
all **public** state variables. For the contract given below, the compiler will
|
||||||
generate a function called ``data`` that does not take any
|
generate a function called ``data`` that does not take any
|
||||||
arguments and returns a ``uint``, the value of the state
|
arguments and returns a ``uint``, the value of the state
|
||||||
variable ``data``. The initialization of state variables can
|
variable ``data``. State variables can be initialized
|
||||||
be done at declaration.
|
when they are declared.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -240,8 +239,8 @@ be done at declaration.
|
|||||||
|
|
||||||
contract Caller {
|
contract Caller {
|
||||||
C c = new C();
|
C c = new C();
|
||||||
function f() public {
|
function f() public view returns (uint) {
|
||||||
uint local = c.data();
|
return c.data();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,9 +255,9 @@ it is evaluated as a state variable. If it is accessed externally
|
|||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
uint public data;
|
uint public data;
|
||||||
function x() public {
|
function x() public returns (uint) {
|
||||||
data = 3; // internal access
|
data = 3; // internal access
|
||||||
uint val = this.data(); // external access
|
return this.data(); // external access
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -615,14 +614,13 @@ Like any function, the fallback function can execute complex operations as long
|
|||||||
}
|
}
|
||||||
|
|
||||||
contract Caller {
|
contract Caller {
|
||||||
function callTest(Test test) public {
|
function callTest(Test test) public returns (bool) {
|
||||||
address(test).call(abi.encodeWithSignature("nonExistingFunction()"));
|
require(address(test).call(abi.encodeWithSignature("nonExistingFunction()")));
|
||||||
// results in test.x becoming == 1.
|
// results in test.x becoming == 1.
|
||||||
|
|
||||||
// If someone sends ether to that contract,
|
// If someone sends ether to that contract,
|
||||||
// the transaction will fail and reject the
|
// the transfer will fail, i.e. this returns false here.
|
||||||
// Ether.
|
return address(test).send(2 ether);
|
||||||
address(test).send(2 ether);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,9 +631,11 @@ Like any function, the fallback function can execute complex operations as long
|
|||||||
Function Overloading
|
Function Overloading
|
||||||
====================
|
====================
|
||||||
|
|
||||||
A Contract can have multiple functions of the same name but with different arguments.
|
A contract can have multiple functions of the same name but with different parameter
|
||||||
This also applies to inherited functions. The following example shows overloading of the
|
types.
|
||||||
``f`` function in the scope of contract ``A``.
|
This process is called "overloading" and also applies to inherited functions.
|
||||||
|
The following example shows overloading of the function
|
||||||
|
``f`` in the scope of contract ``A``.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -643,11 +643,12 @@ This also applies to inherited functions. The following example shows overloadin
|
|||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
function f(uint _in) public pure returns (uint out) {
|
function f(uint _in) public pure returns (uint out) {
|
||||||
out = 1;
|
out = _in;
|
||||||
}
|
}
|
||||||
|
|
||||||
function f(uint _in, bytes32 _key) public pure returns (uint out) {
|
function f(uint _in, bool _really) public pure returns (uint out) {
|
||||||
out = 2;
|
if (_really)
|
||||||
|
out = _in;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -656,9 +657,9 @@ externally visible functions differ by their Solidity types but not by their ext
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
// This will not compile
|
|
||||||
pragma solidity ^0.4.16;
|
pragma solidity ^0.4.16;
|
||||||
|
|
||||||
|
// This will not compile
|
||||||
contract A {
|
contract A {
|
||||||
function f(B _in) public pure returns (B out) {
|
function f(B _in) public pure returns (B out) {
|
||||||
out = _in;
|
out = _in;
|
||||||
@ -1037,10 +1038,12 @@ derived contracts need to specify all of them. This can be done in two ways::
|
|||||||
constructor(uint _x) public { x = _x; }
|
constructor(uint _x) public { x = _x; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Either directly specify in the inheritance list...
|
||||||
contract Derived1 is Base(7) {
|
contract Derived1 is Base(7) {
|
||||||
constructor(uint _y) public {}
|
constructor() public {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// or through a "modifier" of the derived constructor.
|
||||||
contract Derived2 is Base {
|
contract Derived2 is Base {
|
||||||
constructor(uint _y) Base(_y * _y) public {}
|
constructor(uint _y) Base(_y * _y) public {}
|
||||||
}
|
}
|
||||||
@ -1079,12 +1082,11 @@ error "Linearization of inheritance graph impossible".
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
// This will not compile
|
|
||||||
|
|
||||||
pragma solidity ^0.4.0;
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
contract X {}
|
contract X {}
|
||||||
contract A is X {}
|
contract A is X {}
|
||||||
|
// This will not compile
|
||||||
contract C is A, X {}
|
contract C is A, X {}
|
||||||
|
|
||||||
The reason for this is that ``C`` requests ``X`` to override ``A``
|
The reason for this is that ``C`` requests ``X`` to override ``A``
|
||||||
@ -1342,6 +1344,7 @@ custom types without the overhead of external function calls:
|
|||||||
BigInt.bigint memory x = BigInt.fromUint(7);
|
BigInt.bigint memory x = BigInt.fromUint(7);
|
||||||
BigInt.bigint memory y = BigInt.fromUint(uint(-1));
|
BigInt.bigint memory y = BigInt.fromUint(uint(-1));
|
||||||
BigInt.bigint memory z = x.add(y);
|
BigInt.bigint memory z = x.add(y);
|
||||||
|
assert(z.limb(1) > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,8 +23,9 @@ something like::
|
|||||||
pragma solidity ^0.4.16;
|
pragma solidity ^0.4.16;
|
||||||
|
|
||||||
contract Simple {
|
contract Simple {
|
||||||
function taker(uint _a, uint _b) public pure {
|
uint sum;
|
||||||
// do something with _a and _b.
|
function taker(uint _a, uint _b) public {
|
||||||
|
sum = _a + _b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +103,7 @@ this nonsensical example::
|
|||||||
pragma solidity ^0.4.16;
|
pragma solidity ^0.4.16;
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
function g(uint a) public pure returns (uint ret) { return f(); }
|
function g(uint a) public pure returns (uint ret) { return a + f(); }
|
||||||
function f() internal pure returns (uint ret) { return g(7) + f(); }
|
function f() internal pure returns (uint ret) { return g(7) + f(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,8 +159,8 @@ throws an exception or goes out of gas.
|
|||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
Any interaction with another contract imposes a potential danger, especially
|
Any interaction with another contract imposes a potential danger, especially
|
||||||
if the source code of the contract is not known in advance. The current
|
if the source code of the contract is not known in advance. The
|
||||||
contract hands over control to the called contract and that may potentially
|
current contract hands over control to the called contract and that may potentially
|
||||||
do just about anything. Even if the called contract inherits from a known parent contract,
|
do just about anything. Even if the called contract inherits from a known parent contract,
|
||||||
the inheriting contract is only required to have a correct interface. The
|
the inheriting contract is only required to have a correct interface. The
|
||||||
implementation of the contract, however, can be completely arbitrary and thus,
|
implementation of the contract, however, can be completely arbitrary and thus,
|
||||||
@ -184,14 +185,16 @@ parameters from the function declaration, but can be in arbitrary order.
|
|||||||
pragma solidity ^0.4.0;
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
function f(uint key, uint value) public {
|
mapping(uint => uint) data;
|
||||||
// ...
|
|
||||||
|
function f() public {
|
||||||
|
set({value: 2, key: 3});
|
||||||
}
|
}
|
||||||
|
|
||||||
function g() public {
|
function set(uint key, uint value) public {
|
||||||
// named arguments
|
data[key] = value;
|
||||||
f({value: 2, key: 3});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Omitted Function Parameter Names
|
Omitted Function Parameter Names
|
||||||
@ -228,7 +231,7 @@ creation-dependencies are not possible.
|
|||||||
pragma solidity >0.4.24;
|
pragma solidity >0.4.24;
|
||||||
|
|
||||||
contract D {
|
contract D {
|
||||||
uint x;
|
uint public x;
|
||||||
constructor(uint a) public payable {
|
constructor(uint a) public payable {
|
||||||
x = a;
|
x = a;
|
||||||
}
|
}
|
||||||
@ -239,11 +242,13 @@ creation-dependencies are not possible.
|
|||||||
|
|
||||||
function createD(uint arg) public {
|
function createD(uint arg) public {
|
||||||
D newD = new D(arg);
|
D newD = new D(arg);
|
||||||
|
newD.x();
|
||||||
}
|
}
|
||||||
|
|
||||||
function createAndEndowD(uint arg, uint amount) public payable {
|
function createAndEndowD(uint arg, uint amount) public payable {
|
||||||
// Send ether along with the creation
|
// Send ether along with the creation
|
||||||
D newD = (new D).value(amount)(arg);
|
D newD = (new D).value(amount)(arg);
|
||||||
|
newD.x();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,8 +292,9 @@ These can then either be assigned to newly declared variables or to pre-existing
|
|||||||
}
|
}
|
||||||
|
|
||||||
function g() public {
|
function g() public {
|
||||||
// Variables declared with type and assigned from the returned tuple.
|
// Variables declared with type and assigned from the returned tuple,
|
||||||
(uint x, bool b, uint y) = f();
|
// not all elements have to be specified (but the number must match).
|
||||||
|
(uint x, , uint y) = f();
|
||||||
// Common trick to swap values -- does not work for non-value storage types.
|
// Common trick to swap values -- does not work for non-value storage types.
|
||||||
(x, y) = (y, x);
|
(x, y) = (y, x);
|
||||||
// Components can be left out (also for variable declarations).
|
// Components can be left out (also for variable declarations).
|
||||||
@ -338,11 +344,13 @@ the two variables have the same name but disjoint scopes.
|
|||||||
contract C {
|
contract C {
|
||||||
function minimalScoping() pure public {
|
function minimalScoping() pure public {
|
||||||
{
|
{
|
||||||
uint same2 = 0;
|
uint same;
|
||||||
|
same = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
uint same2 = 0;
|
uint same;
|
||||||
|
same = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -354,6 +362,7 @@ In any case, you will get a warning about the outer variable being shadowed.
|
|||||||
::
|
::
|
||||||
|
|
||||||
pragma solidity >0.4.24;
|
pragma solidity >0.4.24;
|
||||||
|
// This will report a warning
|
||||||
contract C {
|
contract C {
|
||||||
function f() pure public returns (uint) {
|
function f() pure public returns (uint) {
|
||||||
uint x = 1;
|
uint x = 1;
|
||||||
@ -372,9 +381,8 @@ In any case, you will get a warning about the outer variable being shadowed.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
// This will not compile
|
|
||||||
|
|
||||||
pragma solidity >0.4.24;
|
pragma solidity >0.4.24;
|
||||||
|
// This will not compile
|
||||||
contract C {
|
contract C {
|
||||||
function f() pure public returns (uint) {
|
function f() pure public returns (uint) {
|
||||||
x = 2;
|
x = 2;
|
||||||
|
@ -62,7 +62,8 @@ Example::
|
|||||||
contract C {
|
contract C {
|
||||||
function f() public pure returns (uint8[5] memory) {
|
function f() public pure returns (uint8[5] memory) {
|
||||||
string[4] memory adaArr = ["This", "is", "an", "array"];
|
string[4] memory adaArr = ["This", "is", "an", "array"];
|
||||||
return ([1, 2, 3, 4, 5]);
|
adaArr[0] = "That";
|
||||||
|
return [1, 2, 3, 4, 5];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,9 +187,10 @@ If you do not want to throw, you can return a pair::
|
|||||||
function checkCounter(uint index) public view {
|
function checkCounter(uint index) public view {
|
||||||
(uint counter, bool error) = getCounter(index);
|
(uint counter, bool error) = getCounter(index);
|
||||||
if (error) {
|
if (error) {
|
||||||
// ...
|
// Handle the error
|
||||||
} else {
|
} else {
|
||||||
// ...
|
// Do something with counter.
|
||||||
|
require(counter > 7, "Invalid counter value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -372,15 +374,14 @@ contract level) with ``arrayname.length = <some new length>;``. If you get the
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
// This will not compile
|
|
||||||
|
|
||||||
pragma solidity ^0.4.18;
|
pragma solidity ^0.4.18;
|
||||||
|
|
||||||
|
// This will not compile
|
||||||
contract C {
|
contract C {
|
||||||
int8[] dynamicStorageArray;
|
int8[] dynamicStorageArray;
|
||||||
int8[5] fixedStorageArray;
|
int8[5] fixedStorageArray;
|
||||||
|
|
||||||
function f() {
|
function f() public {
|
||||||
int8[] memory memArr; // Case 1
|
int8[] memory memArr; // Case 1
|
||||||
memArr.length++; // illegal
|
memArr.length++; // illegal
|
||||||
|
|
||||||
|
@ -204,7 +204,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) public returns (uint s, uint p) {
|
function rectangle(uint w, uint h) public pure returns (uint s, uint p) {
|
||||||
s = w * h;
|
s = w * h;
|
||||||
p = 2 * (w + h);
|
p = 2 * (w + h);
|
||||||
}
|
}
|
||||||
|
@ -467,22 +467,22 @@ high or low invalid bids.
|
|||||||
|
|
||||||
uint refund;
|
uint refund;
|
||||||
for (uint i = 0; i < length; i++) {
|
for (uint i = 0; i < length; i++) {
|
||||||
Bid storage bid = bids[msg.sender][i];
|
Bid storage bidToCheck = bids[msg.sender][i];
|
||||||
(uint value, bool fake, bytes32 secret) =
|
(uint value, bool fake, bytes32 secret) =
|
||||||
(_values[i], _fake[i], _secret[i]);
|
(_values[i], _fake[i], _secret[i]);
|
||||||
if (bid.blindedBid != keccak256(abi.encodePacked(value, fake, secret))) {
|
if (bidToCheck.blindedBid != keccak256(abi.encodePacked(value, fake, secret))) {
|
||||||
// Bid was not actually revealed.
|
// Bid was not actually revealed.
|
||||||
// Do not refund deposit.
|
// Do not refund deposit.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
refund += bid.deposit;
|
refund += bidToCheck.deposit;
|
||||||
if (!fake && bid.deposit >= value) {
|
if (!fake && bidToCheck.deposit >= value) {
|
||||||
if (placeBid(msg.sender, value))
|
if (placeBid(msg.sender, value))
|
||||||
refund -= value;
|
refund -= value;
|
||||||
}
|
}
|
||||||
// Make it impossible for the sender to re-claim
|
// Make it impossible for the sender to re-claim
|
||||||
// the same deposit.
|
// the same deposit.
|
||||||
bid.blindedBid = bytes32(0);
|
bidToCheck.blindedBid = bytes32(0);
|
||||||
}
|
}
|
||||||
msg.sender.transfer(refund);
|
msg.sender.transfer(refund);
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ Function modifiers can be used to amend the semantics of functions in a declarat
|
|||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
|
|
||||||
function abort() public onlySeller { // Modifier usage
|
function abort() public view onlySeller { // Modifier usage
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,31 +52,35 @@ Surround top level declarations in solidity source with two blank lines.
|
|||||||
|
|
||||||
Yes::
|
Yes::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
contract B {
|
contract B {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
contract B {
|
contract B {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
Within a contract surround function declarations with a single blank line.
|
Within a contract surround function declarations with a single blank line.
|
||||||
@ -85,30 +89,34 @@ Blank lines may be omitted between groups of related one-liners (such as stub fu
|
|||||||
|
|
||||||
Yes::
|
Yes::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
function spam() public;
|
function spam() public pure;
|
||||||
function ham() public;
|
function ham() public pure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
contract B is A {
|
contract B is A {
|
||||||
function spam() public {
|
function spam() public pure {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
function ham() public {
|
function ham() public pure {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
function spam() public {
|
function spam() public pure {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
function ham() public {
|
function ham() public pure {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,22 +237,24 @@ Import statements should always be placed at the top of the file.
|
|||||||
|
|
||||||
Yes::
|
Yes::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
import "./Owned.sol";
|
import "./Owned.sol";
|
||||||
|
|
||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
contract B is Owned {
|
contract B is Owned {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -252,7 +262,7 @@ No::
|
|||||||
|
|
||||||
|
|
||||||
contract B is Owned {
|
contract B is Owned {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
Order of Functions
|
Order of Functions
|
||||||
@ -273,13 +283,15 @@ Within a grouping, place the ``view`` and ``pure`` functions last.
|
|||||||
|
|
||||||
Yes::
|
Yes::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
constructor() public {
|
constructor() public {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
function() external {
|
function() external {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
// External functions
|
// External functions
|
||||||
@ -303,13 +315,15 @@ Yes::
|
|||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
contract A {
|
contract A {
|
||||||
|
|
||||||
// External functions
|
// External functions
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
function() external {
|
function() external {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
// Private functions
|
// Private functions
|
||||||
@ -319,7 +333,7 @@ No::
|
|||||||
// ...
|
// ...
|
||||||
|
|
||||||
constructor() public {
|
constructor() public {
|
||||||
...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal functions
|
// Internal functions
|
||||||
@ -397,6 +411,8 @@ should:
|
|||||||
|
|
||||||
Yes::
|
Yes::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
contract Coin {
|
contract Coin {
|
||||||
struct Bank {
|
struct Bank {
|
||||||
address owner;
|
address owner;
|
||||||
@ -406,6 +422,8 @@ Yes::
|
|||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
contract Coin
|
contract Coin
|
||||||
{
|
{
|
||||||
struct Bank {
|
struct Bank {
|
||||||
@ -705,7 +723,25 @@ manner as modifiers if the function declaration is long or hard to read.
|
|||||||
|
|
||||||
Yes::
|
Yes::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
|
// Base contracts just to make this compile
|
||||||
|
contract B {
|
||||||
|
constructor(uint) public {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contract C {
|
||||||
|
constructor(uint, uint) public {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contract D {
|
||||||
|
constructor(uint) public {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
contract A is B, C, D {
|
contract A is B, C, D {
|
||||||
|
uint x;
|
||||||
|
|
||||||
constructor(uint param1, uint param2, uint param3, uint param4, uint param5)
|
constructor(uint param1, uint param2, uint param3, uint param4, uint param5)
|
||||||
B(param1)
|
B(param1)
|
||||||
C(param2, param3)
|
C(param2, param3)
|
||||||
@ -713,29 +749,50 @@ Yes::
|
|||||||
public
|
public
|
||||||
{
|
{
|
||||||
// do something with param5
|
// do something with param5
|
||||||
|
x = param5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
|
// Base contracts just to make this compile
|
||||||
|
contract B {
|
||||||
|
constructor(uint) public {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contract C {
|
||||||
|
constructor(uint, uint) public {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contract D {
|
||||||
|
constructor(uint) public {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
contract A is B, C, D {
|
contract A is B, C, D {
|
||||||
|
uint x;
|
||||||
|
|
||||||
constructor(uint param1, uint param2, uint param3, uint param4, uint param5)
|
constructor(uint param1, uint param2, uint param3, uint param4, uint param5)
|
||||||
B(param1)
|
B(param1)
|
||||||
C(param2, param3)
|
C(param2, param3)
|
||||||
D(param4)
|
D(param4)
|
||||||
public
|
public
|
||||||
{
|
{
|
||||||
// do something with param5
|
x = param5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
contract A is B, C, D {
|
contract X is B, C, D {
|
||||||
|
uint x;
|
||||||
|
|
||||||
constructor(uint param1, uint param2, uint param3, uint param4, uint param5)
|
constructor(uint param1, uint param2, uint param3, uint param4, uint param5)
|
||||||
B(param1)
|
B(param1)
|
||||||
C(param2, param3)
|
C(param2, param3)
|
||||||
D(param4)
|
D(param4)
|
||||||
public {
|
public {
|
||||||
// do something with param5
|
x = param5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -875,6 +932,8 @@ As shown in the example below, if the contract name is `Congress` and the librar
|
|||||||
|
|
||||||
Yes::
|
Yes::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
// Owned.sol
|
// Owned.sol
|
||||||
contract Owned {
|
contract Owned {
|
||||||
address public owner;
|
address public owner;
|
||||||
@ -897,11 +956,13 @@ Yes::
|
|||||||
import "./Owned.sol";
|
import "./Owned.sol";
|
||||||
|
|
||||||
contract Congress is Owned, TokenRecipient {
|
contract Congress is Owned, TokenRecipient {
|
||||||
...
|
//...
|
||||||
}
|
}
|
||||||
|
|
||||||
No::
|
No::
|
||||||
|
|
||||||
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
// owned.sol
|
// owned.sol
|
||||||
contract owned {
|
contract owned {
|
||||||
address public owner;
|
address public owner;
|
||||||
@ -924,7 +985,7 @@ No::
|
|||||||
import "./owned.sol";
|
import "./owned.sol";
|
||||||
|
|
||||||
contract Congress is owned, tokenRecipient {
|
contract Congress is owned, tokenRecipient {
|
||||||
...
|
//...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -447,7 +447,7 @@ which returns the :ref:`ABI function selector <abi_function_selector>`::
|
|||||||
pragma solidity ^0.4.16;
|
pragma solidity ^0.4.16;
|
||||||
|
|
||||||
contract Selector {
|
contract Selector {
|
||||||
function f() public view returns (bytes4) {
|
function f() public pure returns (bytes4) {
|
||||||
return this.f.selector;
|
return this.f.selector;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -510,15 +510,15 @@ Another example that uses external function types::
|
|||||||
contract Oracle {
|
contract Oracle {
|
||||||
struct Request {
|
struct Request {
|
||||||
bytes data;
|
bytes data;
|
||||||
function(bytes memory) external callback;
|
function(uint) external callback;
|
||||||
}
|
}
|
||||||
Request[] requests;
|
Request[] requests;
|
||||||
event NewRequest(uint);
|
event NewRequest(uint);
|
||||||
function query(bytes memory data, function(bytes memory) external callback) public {
|
function query(bytes memory data, function(uint) external callback) public {
|
||||||
requests.push(Request(data, callback));
|
requests.push(Request(data, callback));
|
||||||
emit NewRequest(requests.length - 1);
|
emit NewRequest(requests.length - 1);
|
||||||
}
|
}
|
||||||
function reply(uint requestID, bytes memory response) public {
|
function reply(uint requestID, uint response) public {
|
||||||
// Here goes the check that the reply comes from a trusted source
|
// Here goes the check that the reply comes from a trusted source
|
||||||
requests[requestID].callback(response);
|
requests[requestID].callback(response);
|
||||||
}
|
}
|
||||||
@ -526,15 +526,16 @@ 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
|
||||||
|
uint exchangeRate;
|
||||||
function buySomething() public {
|
function buySomething() public {
|
||||||
oracle.query("USD", this.oracleResponse);
|
oracle.query("USD", this.oracleResponse);
|
||||||
}
|
}
|
||||||
function oracleResponse(bytes memory response) public {
|
function oracleResponse(uint response) public {
|
||||||
require(
|
require(
|
||||||
msg.sender == address(oracle),
|
msg.sender == address(oracle),
|
||||||
"Only oracle can call this."
|
"Only oracle can call this."
|
||||||
);
|
);
|
||||||
// Use the data
|
exchangeRate = response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,8 +602,8 @@ memory-stored reference type do not create a copy.
|
|||||||
h(x); // calls h and creates an independent, temporary copy in memory
|
h(x); // calls h and creates an independent, temporary copy in memory
|
||||||
}
|
}
|
||||||
|
|
||||||
function g(uint[] storage storageArray) internal {}
|
function g(uint[] storage) internal pure {}
|
||||||
function h(uint[] memory memoryArray) public {}
|
function h(uint[] memory) public pure {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Summary
|
Summary
|
||||||
@ -659,8 +660,9 @@ Allocating Memory Arrays
|
|||||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Creating arrays with variable length in memory can be done using the ``new`` keyword.
|
Creating arrays with variable length in memory can be done using the ``new`` keyword.
|
||||||
As opposed to storage arrays, it is **not** possible to resize memory arrays by assigning to
|
As opposed to storage arrays, it is **not** possible to resize memory arrays (e.g. by assigning to
|
||||||
the ``.length`` member.
|
the ``.length`` member). You either have to calculate the required size in advance
|
||||||
|
or create a new memory array and copy every element.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@ -670,7 +672,8 @@ the ``.length`` member.
|
|||||||
function f(uint len) public pure {
|
function f(uint len) public pure {
|
||||||
uint[] memory a = new uint[](7);
|
uint[] memory a = new uint[](7);
|
||||||
bytes memory b = new bytes(len);
|
bytes memory b = new bytes(len);
|
||||||
// Here we have a.length == 7 and b.length == len
|
assert(a.length == 7);
|
||||||
|
assert(b.length == len);
|
||||||
a[6] = 8;
|
a[6] = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -691,7 +694,7 @@ assigned to a variable right away.
|
|||||||
function f() public pure {
|
function f() public pure {
|
||||||
g([uint(1), 2, 3]);
|
g([uint(1), 2, 3]);
|
||||||
}
|
}
|
||||||
function g(uint[3] memory _data) public pure {
|
function g(uint[3] memory) public pure {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -706,10 +709,9 @@ possible:
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
// This will not compile.
|
|
||||||
|
|
||||||
pragma solidity ^0.4.0;
|
pragma solidity ^0.4.0;
|
||||||
|
|
||||||
|
// This will not compile.
|
||||||
contract C {
|
contract C {
|
||||||
function f() public {
|
function f() public {
|
||||||
// The next line creates a type error because uint[3] memory
|
// The next line creates a type error because uint[3] memory
|
||||||
@ -752,9 +754,12 @@ Members
|
|||||||
uint[2**20] m_aLotOfIntegers;
|
uint[2**20] m_aLotOfIntegers;
|
||||||
// Note that the following is not a pair of dynamic arrays but a
|
// Note that the following is not a pair of dynamic arrays but a
|
||||||
// dynamic array of pairs (i.e. of fixed size arrays of length two).
|
// dynamic array of pairs (i.e. of fixed size arrays of length two).
|
||||||
|
// Because of that, T[] is always a dynamic array of T, even if T
|
||||||
|
// itself is an array.
|
||||||
bool[2][] m_pairsOfFlags;
|
bool[2][] m_pairsOfFlags;
|
||||||
// newPairs is stored in memory - the default for function arguments
|
|
||||||
|
|
||||||
|
// newPairs is stored in memory - the only possibility
|
||||||
|
// for public function arguments
|
||||||
function setAllFlagPairs(bool[2][] memory newPairs) public {
|
function setAllFlagPairs(bool[2][] memory newPairs) public {
|
||||||
// assignment to a storage array replaces the complete array
|
// assignment to a storage array replaces the complete array
|
||||||
m_pairsOfFlags = newPairs;
|
m_pairsOfFlags = newPairs;
|
||||||
@ -797,6 +802,11 @@ Members
|
|||||||
function createMemoryArray(uint size) public pure returns (bytes memory) {
|
function createMemoryArray(uint size) public pure returns (bytes memory) {
|
||||||
// Dynamic memory arrays are created using `new`:
|
// Dynamic memory arrays are created using `new`:
|
||||||
uint[2][] memory arrayOfPairs = new uint[2][](size);
|
uint[2][] memory arrayOfPairs = new uint[2][](size);
|
||||||
|
|
||||||
|
// Inline arrays are always statically-sized and if you only
|
||||||
|
// use literals, you have to provide at least one type.
|
||||||
|
arrayOfPairs[0] = [uint(1), 2];
|
||||||
|
|
||||||
// Create a dynamic byte array:
|
// Create a dynamic byte array:
|
||||||
bytes memory b = new bytes(200);
|
bytes memory b = new bytes(200);
|
||||||
for (uint i = 0; i < b.length; i++)
|
for (uint i = 0; i < b.length; i++)
|
||||||
@ -968,6 +978,7 @@ It is important to note that ``delete a`` really behaves like an assignment to `
|
|||||||
// y is affected which is an alias to the storage object
|
// y is affected which is an alias to the storage object
|
||||||
// On the other hand: "delete y" is not valid, as assignments to local variables
|
// On the other hand: "delete y" is not valid, as assignments to local variables
|
||||||
// referencing storage objects can only be made from existing storage objects.
|
// referencing storage objects can only be made from existing storage objects.
|
||||||
|
assert(y.length == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,43 +35,26 @@ def extract_test_cases(path):
|
|||||||
return tests
|
return tests
|
||||||
|
|
||||||
# Contract sources are indented by 4 spaces.
|
# Contract sources are indented by 4 spaces.
|
||||||
# Look for `pragma solidity` and abort a line not indented properly.
|
# Look for `pragma solidity`, `contract`, `library` or `interface`
|
||||||
# If the comment `// This will not compile` is above the pragma,
|
# and abort a line not indented properly.
|
||||||
# the code is skipped.
|
|
||||||
def extract_docs_cases(path):
|
def extract_docs_cases(path):
|
||||||
# Note: this code works, because splitlines() removes empty new lines
|
|
||||||
# and thus even if the empty new lines are missing indentation
|
|
||||||
lines = open(path, 'rb').read().splitlines()
|
|
||||||
|
|
||||||
ignore = False
|
|
||||||
inside = False
|
inside = False
|
||||||
tests = []
|
tests = []
|
||||||
|
|
||||||
for l in lines:
|
# Collect all snippets of indented blocks
|
||||||
|
for l in open(path, 'rb').read().splitlines():
|
||||||
|
if l != '':
|
||||||
|
if not inside and l.startswith(' '):
|
||||||
|
# start new test
|
||||||
|
tests += ['']
|
||||||
|
inside = l.startswith(' ')
|
||||||
if inside:
|
if inside:
|
||||||
# Abort if indentation is missing
|
|
||||||
m = re.search(r'^[^ ]+', l)
|
|
||||||
if m:
|
|
||||||
inside = False
|
|
||||||
else:
|
|
||||||
tests[-1] += l + '\n'
|
tests[-1] += l + '\n'
|
||||||
else:
|
# Filter all tests that do not contain Solidity
|
||||||
m = re.search(r'^ // This will not compile', l)
|
return [
|
||||||
if m:
|
test for test in tests
|
||||||
ignore = True
|
if re.search(r'^ [ ]*(pragma solidity|contract |library |interface )', test, re.MULTILINE)
|
||||||
|
]
|
||||||
if ignore:
|
|
||||||
# Abort if indentation is missing
|
|
||||||
m = re.search(r'^[^ ]+', l)
|
|
||||||
if m:
|
|
||||||
ignore = False
|
|
||||||
else:
|
|
||||||
m = re.search(r'^ pragma solidity .*[0-9]+\.[0-9]+\.[0-9]+;$', l)
|
|
||||||
if m:
|
|
||||||
inside = True
|
|
||||||
tests += [l]
|
|
||||||
|
|
||||||
return tests
|
|
||||||
|
|
||||||
def write_cases(tests):
|
def write_cases(tests):
|
||||||
for test in tests:
|
for test in tests:
|
||||||
|
@ -43,18 +43,42 @@ function printError() { echo "$(tput setaf 1)$1$(tput sgr0)"; }
|
|||||||
|
|
||||||
function compileFull()
|
function compileFull()
|
||||||
{
|
{
|
||||||
|
local expected_exit_code=0
|
||||||
|
local expect_output=0
|
||||||
|
if [[ $1 = '-e' ]]
|
||||||
|
then
|
||||||
|
expected_exit_code=1
|
||||||
|
expect_output=1
|
||||||
|
shift;
|
||||||
|
fi
|
||||||
|
if [[ $1 = '-w' ]]
|
||||||
|
then
|
||||||
|
expect_output=1
|
||||||
|
shift;
|
||||||
|
fi
|
||||||
|
|
||||||
local files="$*"
|
local files="$*"
|
||||||
local output failed
|
local output
|
||||||
|
|
||||||
|
local stderr_path=$(mktemp)
|
||||||
|
|
||||||
set +e
|
set +e
|
||||||
output=$( ("$SOLC" $FULLARGS $files) 2>&1 )
|
"$SOLC" $FULLARGS $files >/dev/null 2>"$stderr_path"
|
||||||
failed=$?
|
local exit_code=$?
|
||||||
|
local errors=$(grep -v -E 'Warning: This is a pre-release compiler version|Warning: Experimental features are turned on|pragma experimental ABIEncoderV2|\^-------------------------------\^' < "$stderr_path")
|
||||||
set -e
|
set -e
|
||||||
|
rm "$stderr_path"
|
||||||
|
|
||||||
if [ $failed -ne 0 ]
|
if [[ \
|
||||||
|
"$exit_code" -ne "$expected_exit_code" || \
|
||||||
|
( $expect_output -eq 0 && -n "$errors" ) || \
|
||||||
|
( $expect_output -ne 0 && -z "$errors" ) \
|
||||||
|
]]
|
||||||
then
|
then
|
||||||
printError "Compilation failed on:"
|
printError "Unexpected compilation result:"
|
||||||
echo "$output"
|
printError "Expected failure: $expected_exit_code - Expected warning / error output: $expect_output"
|
||||||
|
printError "Was failure: $exit_code"
|
||||||
|
echo "$errors"
|
||||||
printError "While calling:"
|
printError "While calling:"
|
||||||
echo "\"$SOLC\" $FULLARGS $files"
|
echo "\"$SOLC\" $FULLARGS $files"
|
||||||
printError "Inside directory:"
|
printError "Inside directory:"
|
||||||
@ -63,22 +87,6 @@ function compileFull()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function compileWithoutWarning()
|
|
||||||
{
|
|
||||||
local files="$*"
|
|
||||||
local output failed
|
|
||||||
|
|
||||||
set +e
|
|
||||||
output=$("$SOLC" $files 2>&1)
|
|
||||||
failed=$?
|
|
||||||
# Remove the pre-release warning from the compiler output
|
|
||||||
output=$(echo "$output" | grep -v 'pre-release')
|
|
||||||
echo "$output"
|
|
||||||
set -e
|
|
||||||
|
|
||||||
test -z "$output" -a "$failed" -eq 0
|
|
||||||
}
|
|
||||||
|
|
||||||
printTask "Testing unknown options..."
|
printTask "Testing unknown options..."
|
||||||
(
|
(
|
||||||
set +e
|
set +e
|
||||||
@ -157,7 +165,7 @@ do
|
|||||||
then
|
then
|
||||||
echo " - $dir"
|
echo " - $dir"
|
||||||
cd "$dir"
|
cd "$dir"
|
||||||
compileFull *.sol */*.sol
|
compileFull -w *.sol */*.sol
|
||||||
cd ..
|
cd ..
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@ -173,8 +181,25 @@ TMPDIR=$(mktemp -d)
|
|||||||
"$REPO_ROOT"/scripts/isolate_tests.py "$REPO_ROOT"/docs/ docs
|
"$REPO_ROOT"/scripts/isolate_tests.py "$REPO_ROOT"/docs/ docs
|
||||||
for f in *.sol
|
for f in *.sol
|
||||||
do
|
do
|
||||||
|
# The contributors guide uses syntax tests, but we cannot
|
||||||
|
# really handle them here.
|
||||||
|
if grep -E 'DeclarationError:|// ----' "$f" >/dev/null
|
||||||
|
then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
echo "$f"
|
echo "$f"
|
||||||
compileFull "$TMPDIR/$f"
|
opts=''
|
||||||
|
# We expect errors if explicitly stated, or if imports
|
||||||
|
# are used (in the style guide)
|
||||||
|
if grep -E "This will not compile|import \"" "$f" >/dev/null
|
||||||
|
then
|
||||||
|
opts="-e"
|
||||||
|
fi
|
||||||
|
if grep "This will report a warning" "$f" >/dev/null
|
||||||
|
then
|
||||||
|
opts="$opts -w"
|
||||||
|
fi
|
||||||
|
compileFull $opts "$TMPDIR/$f"
|
||||||
done
|
done
|
||||||
)
|
)
|
||||||
rm -rf "$TMPDIR"
|
rm -rf "$TMPDIR"
|
||||||
|
Loading…
Reference in New Issue
Block a user