Merge remote-tracking branch 'origin/develop' into breaking

This commit is contained in:
chriseth
2020-05-26 10:11:23 +02:00
65 changed files with 763 additions and 205 deletions
+75
View File
@@ -78,6 +78,81 @@ private:
BOOST_FIXTURE_TEST_SUITE(SolidityNatspecJSON, DocumentationChecker)
BOOST_AUTO_TEST_CASE(user_empty_natspec_test)
{
char const* sourceCode = R"(
contract test {
///
///
function f() public {
}
}
)";
char const* natspec = R"(
{
"methods": {}
}
)";
checkNatspec(sourceCode, "test", natspec, true);
}
BOOST_AUTO_TEST_CASE(user_newline_break)
{
char const* sourceCode = R"(
contract test {
///
/// @notice hello
/// @notice world
function f() public {
}
}
)";
char const* natspec = R"ABCDEF(
{
"methods": {
"f()":
{
"notice": "world"
}
}
}
)ABCDEF";
checkNatspec(sourceCode, "test", natspec, true);
}
BOOST_AUTO_TEST_CASE(user_multiline_empty_lines)
{
char const* sourceCode = R"(
contract test {
/**
*
*
* @notice hello world
*/
function f() public {
}
}
)";
char const* natspec = R"ABCDEF(
{
"methods": {
"f()": {
"notice": "hello world"
}
}
}
)ABCDEF";
checkNatspec(sourceCode, "test", natspec, true);
}
BOOST_AUTO_TEST_CASE(user_basic_test)
{
char const* sourceCode = R"(
+2 -2
View File
@@ -361,7 +361,7 @@ BOOST_AUTO_TEST_CASE(multiline_documentation_comments_parsed)
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
BOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), "Send $(value / 1000) chocolates to the user");
BOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), " Send $(value / 1000) chocolates to the user");
}
BOOST_AUTO_TEST_CASE(multiline_documentation_no_stars)
@@ -385,7 +385,7 @@ BOOST_AUTO_TEST_CASE(multiline_documentation_whitespace_hell)
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
BOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), "Send $(value / 1000) chocolates to the user");
BOOST_CHECK_EQUAL(scanner.currentCommentLiteral(), " Send $(value / 1000) chocolates to the user");
}
BOOST_AUTO_TEST_CASE(comment_before_eos)
@@ -0,0 +1,18 @@
library L {
function equals(address a, address b) internal pure returns (bool) {
return a == b;
}
}
contract C {
using L for address;
function foo(address a, address b) public returns (bool) {
return a.equals(b);
}
}
// ====
// compileViaYul: also
// ----
// foo(address, address): 0x111122223333444455556666777788889999aAaa, 0x111122223333444455556666777788889999aAaa -> true
// foo(address, address): 0x111122223333444455556666777788889999aAaa, 0x0000000000000000000000000000000000000000 -> false
@@ -0,0 +1,21 @@
library L {
function transfer(address a) internal {}
function send(address a) internal {}
}
contract C {
using L for address;
function useTransfer(address a) public {
a.transfer();
}
function useSend(address a) public {
a.send();
}
}
// ====
// compileViaYul: also
// ----
// useTransfer(address): 0x111122223333444455556666777788889999aAaa ->
// useSend(address): 0x111122223333444455556666777788889999aAaa ->
@@ -0,0 +1,19 @@
library L {
function pop(uint[2] memory a) internal {}
function push(uint[2] memory a) internal {}
}
contract C {
using L for uint[2];
function test() public {
uint[2] memory input;
input.push();
input.pop();
}
}
// ====
// compileViaYul: also
// ----
// test() ->
@@ -0,0 +1,20 @@
library L {
function xor(bool a, bool b) internal pure returns (bool) {
return a != b;
}
}
contract C {
using L for bool;
function foo(bool a, bool b) public returns (bool) {
return a.xor(b);
}
}
// ====
// compileViaYul: also
// ----
// foo(bool, bool): true, true -> false
// foo(bool, bool): true, false -> true
// foo(bool, bool): false, true -> true
// foo(bool, bool): false, false -> false
@@ -0,0 +1,21 @@
contract E {}
library L {
function foo(E e) internal pure returns (uint) {
return 42;
}
}
contract C {
using L for E;
function test() public returns (uint) {
E e = new E();
return e.foo();
}
}
// ====
// compileViaYul: also
// ----
// test() -> 42
@@ -0,0 +1,21 @@
library L {
function at(uint[] memory a, uint i) internal pure returns (uint) {
return a[i];
}
}
contract C {
using L for uint[];
function secondItem() public returns (uint) {
uint[] memory input = new uint[](2);
input[0] = 0x11;
input[1] = 0x22;
return input.at(1);
}
}
// ====
// compileViaYul: also
// ----
// secondItem() -> 0x22
@@ -0,0 +1,21 @@
library L {
enum E { A, B }
function equals(E a, E b) internal pure returns (bool) {
return a == b;
}
}
contract C {
using L for L.E;
function equalsA(uint choice) public returns (bool) {
L.E x = L.E.A;
return x.equals(L.E(choice));
}
}
// ====
// compileViaYul: also
// ----
// equalsA(uint256): 0 -> true
// equalsA(uint256): 1 -> false
@@ -0,0 +1,23 @@
library L {
// NOTE: External function takes up two stack slots
function double(function(uint) external pure returns (uint) f, uint x) internal pure returns (uint) {
return f(x) * 2;
}
}
contract C {
using L for function(uint) external pure returns (uint);
function identity(uint x) external pure returns (uint) {
return x;
}
function test(uint value) public returns (uint) {
return this.identity.double(value);
}
}
// ====
// compileViaYul: also
// ----
// test(uint256): 5 -> 10
@@ -0,0 +1,21 @@
library L {
function at(uint[2] memory a, uint i) internal pure returns (uint) {
return a[i];
}
}
contract C {
using L for uint[2];
function secondItem() public returns (uint) {
uint[2] memory input;
input[0] = 0x11;
input[1] = 0x22;
return input.at(1);
}
}
// ====
// compileViaYul: also
// ----
// secondItem() -> 0x22
@@ -0,0 +1,17 @@
library L {
function add(bytes2 a, bytes2 b) internal pure returns (bytes2) {
return bytes2(uint16(a) + uint16(b));
}
}
contract C {
using L for bytes2;
function sum(bytes2 a, bytes2 b) public returns (bytes2) {
return a.add(b);
}
}
// ====
// compileViaYul: also
// ----
// sum(bytes2, bytes2): left(0x1100), left(0x0022) -> left(0x1122)
@@ -0,0 +1,22 @@
library L {
function selector(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {
return f(x) * 2;
}
}
contract C {
using L for function(uint) internal pure returns (uint);
function identity(uint x) internal pure returns (uint) {
return x;
}
function test(uint value) public returns (uint) {
return identity.selector(value);
}
}
// ====
// compileViaYul: also
// ----
// test(uint256): 5 -> 10
@@ -0,0 +1,17 @@
library L {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
}
contract C {
using L for uint256;
function foo(uint256 a, uint256 b) public returns (uint256) {
return a.add(b);
}
}
// ====
// compileViaYul: also
// ----
// foo(uint256, uint256): 8, 42 -> 50
@@ -0,0 +1,22 @@
interface I {}
contract E is I {}
library L {
function foo(I i) internal pure returns (uint) {
return 42;
}
}
contract C {
using L for I;
function test() public returns (uint) {
E e = new E();
return I(e).foo();
}
}
// ====
// compileViaYul: also
// ----
// test() -> 42
@@ -0,0 +1,22 @@
library L {
function double(function(uint) internal pure returns (uint) f, uint x) internal pure returns (uint) {
return f(x) * 2;
}
}
contract C {
using L for function(uint) internal pure returns (uint);
function identity(uint x) internal pure returns (uint) {
return x;
}
function test(uint value) public returns (uint) {
return identity.double(value);
}
}
// ====
// compileViaYul: also
// ----
// test(uint256): 5 -> 10
@@ -0,0 +1,22 @@
library L {
function at(mapping(uint => uint) storage a, uint i) internal view returns (uint) {
return a[i];
}
}
contract C {
using L for mapping(uint => uint);
mapping(uint => uint) map;
function mapValue(uint a) public returns (uint) {
map[42] = 0x24;
map[66] = 0x66;
return map.at(a);
}
}
// ====
// compileViaYul: also
// ----
// mapValue(uint256): 42 -> 0x24
@@ -0,0 +1,18 @@
library L {
function at(string memory a, uint i) internal pure returns (uint8) {
return uint8(bytes(a)[i]);
}
}
contract C {
using L for string;
function secondChar() public returns (uint8) {
string memory input = "abc";
return input.at(1);
}
}
// ====
// compileViaYul: also
// ----
// secondChar() -> 98
@@ -0,0 +1,17 @@
pragma experimental SMTChecker;
contract C {
uint x;
uint y;
mapping (address => bool) public never_used;
function inc() public {
require(x < 10);
require(y < 10);
if(x == 0) x = 0; // noop state var read
x++;
y++;
assert(y == x);
}
}
@@ -0,0 +1,13 @@
pragma experimental ABIEncoderV2;
contract Test {
struct shouldBug {
bytes[2] deadly;
}
function killer(bytes[2] calldata weapon) pure external {
shouldBug(weapon);
}
}
// ----
// UnimplementedFeatureError: Copying nested dynamic calldata arrays to memory is not implemented in the old code generator.
@@ -0,0 +1,13 @@
pragma experimental ABIEncoderV2;
contract Test {
struct shouldBug {
uint256[][2] deadly;
}
function killer(uint256[][2] calldata weapon) pure external {
shouldBug(weapon);
}
}
// ----
// UnimplementedFeatureError: Copying nested dynamic calldata arrays to memory is not implemented in the old code generator.
@@ -0,0 +1,13 @@
pragma experimental ABIEncoderV2;
contract Test {
struct shouldBug {
uint256[][] deadly;
}
function killer(uint256[][] calldata weapon) pure external {
shouldBug(weapon);
}
}
// ----
// UnimplementedFeatureError: Copying nested dynamic calldata arrays to memory is not implemented in the old code generator.
@@ -0,0 +1,9 @@
pragma experimental ABIEncoderV2;
contract C {
uint[][2] tmp_i;
function i(uint[][2] calldata s) external { tmp_i = s; }
}
// ----
// UnimplementedFeatureError: Copying nested calldata dynamic arrays to storage is not implemented in the old code generator.
@@ -0,0 +1,9 @@
pragma experimental ABIEncoderV2;
contract C {
uint[][] tmp_i;
function i(uint[][] calldata s) external { tmp_i = s; }
}
// ----
// UnimplementedFeatureError: Copying nested calldata dynamic arrays to storage is not implemented in the old code generator.
@@ -0,0 +1,7 @@
contract C {
///
///
function vote(uint id) public {
}
}
// ----