aboutsummaryrefslogtreecommitdiffstats
path: root/test/libsolidity/SolidityExpressionCompiler.cpp
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-11-14 02:33:35 +0800
committerGitHub <noreply@github.com>2018-11-14 02:33:35 +0800
commit1d4f565a64988a3400847d2655ca24f73f234bc6 (patch)
treecaaa6c26e307513505349b50ca4f2a8a9506752b /test/libsolidity/SolidityExpressionCompiler.cpp
parent59dbf8f1085b8b92e8b7eb0ce380cbeb642e97eb (diff)
parent91b6b8a88e76016e0324036cb7a7f9300a1e2439 (diff)
downloaddexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.gz
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.bz2
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.lz
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.xz
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.tar.zst
dexon-solidity-1d4f565a64988a3400847d2655ca24f73f234bc6.zip
Merge pull request #5416 from ethereum/develop
Merge develop into release for 0.5.0
Diffstat (limited to 'test/libsolidity/SolidityExpressionCompiler.cpp')
-rw-r--r--test/libsolidity/SolidityExpressionCompiler.cpp286
1 files changed, 136 insertions, 150 deletions
diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp
index 90d8265c..309cbf0b 100644
--- a/test/libsolidity/SolidityExpressionCompiler.cpp
+++ b/test/libsolidity/SolidityExpressionCompiler.cpp
@@ -77,7 +77,7 @@ Declaration const& resolveDeclaration(
)
{
ASTNode const* scope = &_sourceUnit;
- // bracers are required, cause msvc couldnt handle this macro in for statement
+ // bracers are required, cause msvc couldn't handle this macro in for statement
for (string const& namePart: _namespacedName)
{
auto declarations = _resolver.resolveName(namePart, scope);
@@ -175,12 +175,12 @@ BOOST_AUTO_TEST_CASE(literal_true)
{
char const* sourceCode = R"(
contract test {
- function f() { var x = true; }
+ function f() public { bool x = true; }
}
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH1), 0x1});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x1});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -188,12 +188,12 @@ BOOST_AUTO_TEST_CASE(literal_false)
{
char const* sourceCode = R"(
contract test {
- function f() { var x = false; }
+ function f() { bool x = false; }
}
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH1), 0x0});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x0});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -201,12 +201,12 @@ BOOST_AUTO_TEST_CASE(int_literal)
{
char const* sourceCode = R"(
contract test {
- function f() { var x = 0x12345678901234567890; }
+ function f() { uint x = 0x12345678901234567890; }
}
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH10), 0x12, 0x34, 0x56, 0x78, 0x90,
+ bytes expectation({uint8_t(Instruction::PUSH10), 0x12, 0x34, 0x56, 0x78, 0x90,
0x12, 0x34, 0x56, 0x78, 0x90});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -215,14 +215,14 @@ BOOST_AUTO_TEST_CASE(int_with_wei_ether_subdenomination)
{
char const* sourceCode = R"(
contract test {
- function test () {
- var x = 1 wei;
+ constructor() {
+ uint x = 1 wei;
}
}
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH1), 0x1});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x1});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -231,13 +231,13 @@ BOOST_AUTO_TEST_CASE(int_with_szabo_ether_subdenomination)
char const* sourceCode = R"(
contract test {
function test () {
- var x = 1 szabo;
+ uint x = 1 szabo;
}
}
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH5), 0xe8, 0xd4, 0xa5, 0x10, 0x00});
+ bytes expectation({uint8_t(Instruction::PUSH5), 0xe8, 0xd4, 0xa5, 0x10, 0x00});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -245,14 +245,15 @@ BOOST_AUTO_TEST_CASE(int_with_finney_ether_subdenomination)
{
char const* sourceCode = R"(
contract test {
- function test ()
+ constructor()
{
- var x = 1 finney;
+ uint x = 1 finney;
}
- })";
+ }
+ )";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH7), 0x3, 0x8d, 0x7e, 0xa4, 0xc6, 0x80, 0x00});
+ bytes expectation({uint8_t(Instruction::PUSH7), 0x3, 0x8d, 0x7e, 0xa4, 0xc6, 0x80, 0x00});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -260,14 +261,14 @@ BOOST_AUTO_TEST_CASE(int_with_ether_ether_subdenomination)
{
char const* sourceCode = R"(
contract test {
- function test () {
- var x = 1 ether;
+ constructor() {
+ uint x = 1 ether;
}
}
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH8), 0xd, 0xe0, 0xb6, 0xb3, 0xa7, 0x64, 0x00, 0x00});
+ bytes expectation({uint8_t(Instruction::PUSH8), 0xd, 0xe0, 0xb6, 0xb3, 0xa7, 0x64, 0x00, 0x00});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -275,17 +276,17 @@ BOOST_AUTO_TEST_CASE(comparison)
{
char const* sourceCode = R"(
contract test {
- function f() { var x = (0x10aa < 0x11aa) != true; }
+ function f() { bool x = (0x10aa < 0x11aa) != true; }
}
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH1), 0x1, byte(Instruction::ISZERO), byte(Instruction::ISZERO),
- byte(Instruction::PUSH2), 0x11, 0xaa,
- byte(Instruction::PUSH2), 0x10, 0xaa,
- byte(Instruction::LT), byte(Instruction::ISZERO), byte(Instruction::ISZERO),
- byte(Instruction::EQ),
- byte(Instruction::ISZERO)});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x1, uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::PUSH2), 0x11, 0xaa,
+ uint8_t(Instruction::PUSH2), 0x10, 0xaa,
+ uint8_t(Instruction::LT), uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::EQ),
+ uint8_t(Instruction::ISZERO)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -293,32 +294,32 @@ BOOST_AUTO_TEST_CASE(short_circuiting)
{
char const* sourceCode = R"(
contract test {
- function f() { var x = true != (4 <= 8 + 10 || 9 != 2); }
+ function f() { bool x = true != (4 <= 8 + 10 || 9 != 2); }
}
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation({byte(Instruction::PUSH1), 0x12, // 8 + 10
- byte(Instruction::PUSH1), 0x4,
- byte(Instruction::GT),
- byte(Instruction::ISZERO), // after this we have 4 <= 8 + 10
- byte(Instruction::DUP1),
- byte(Instruction::PUSH1), 0x11,
- byte(Instruction::JUMPI), // short-circuit if it is true
- byte(Instruction::POP),
- byte(Instruction::PUSH1), 0x2,
- byte(Instruction::PUSH1), 0x9,
- byte(Instruction::EQ),
- byte(Instruction::ISZERO), // after this we have 9 != 2
- byte(Instruction::JUMPDEST),
- byte(Instruction::ISZERO), byte(Instruction::ISZERO),
- byte(Instruction::PUSH1), 0x1, byte(Instruction::ISZERO), byte(Instruction::ISZERO),
- byte(Instruction::EQ),
- byte(Instruction::ISZERO)});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x12, // 8 + 10
+ uint8_t(Instruction::PUSH1), 0x4,
+ uint8_t(Instruction::GT),
+ uint8_t(Instruction::ISZERO), // after this we have 4 <= 8 + 10
+ uint8_t(Instruction::DUP1),
+ uint8_t(Instruction::PUSH1), 0x11,
+ uint8_t(Instruction::JUMPI), // short-circuit if it is true
+ uint8_t(Instruction::POP),
+ uint8_t(Instruction::PUSH1), 0x2,
+ uint8_t(Instruction::PUSH1), 0x9,
+ uint8_t(Instruction::EQ),
+ uint8_t(Instruction::ISZERO), // after this we have 9 != 2
+ uint8_t(Instruction::JUMPDEST),
+ uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::PUSH1), 0x1, uint8_t(Instruction::ISZERO), uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::EQ),
+ uint8_t(Instruction::ISZERO)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
-BOOST_AUTO_TEST_CASE(arithmetics)
+BOOST_AUTO_TEST_CASE(arithmetic)
{
char const* sourceCode = R"(
contract test {
@@ -326,37 +327,37 @@ BOOST_AUTO_TEST_CASE(arithmetics)
}
)";
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}});
- bytes expectation({byte(Instruction::PUSH1), 0x1,
- byte(Instruction::PUSH1), 0x2,
- byte(Instruction::PUSH1), 0x3,
- byte(Instruction::PUSH1), 0x4,
- byte(Instruction::PUSH1), 0x5,
- byte(Instruction::PUSH1), 0x6,
- byte(Instruction::PUSH1), 0x7,
- byte(Instruction::PUSH1), 0x8,
- byte(Instruction::DUP9),
- byte(Instruction::XOR),
- byte(Instruction::AND),
- byte(Instruction::OR),
- byte(Instruction::SUB),
- byte(Instruction::ADD),
- byte(Instruction::DUP2),
- byte(Instruction::ISZERO),
- byte(Instruction::ISZERO),
- byte(Instruction::PUSH1), 0x1d,
- byte(Instruction::JUMPI),
- byte(Instruction::INVALID),
- byte(Instruction::JUMPDEST),
- byte(Instruction::MOD),
- byte(Instruction::DUP2),
- byte(Instruction::ISZERO),
- byte(Instruction::ISZERO),
- byte(Instruction::PUSH1), 0x26,
- byte(Instruction::JUMPI),
- byte(Instruction::INVALID),
- byte(Instruction::JUMPDEST),
- byte(Instruction::DIV),
- byte(Instruction::MUL)});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x1,
+ uint8_t(Instruction::PUSH1), 0x2,
+ uint8_t(Instruction::PUSH1), 0x3,
+ uint8_t(Instruction::PUSH1), 0x4,
+ uint8_t(Instruction::PUSH1), 0x5,
+ uint8_t(Instruction::PUSH1), 0x6,
+ uint8_t(Instruction::PUSH1), 0x7,
+ uint8_t(Instruction::PUSH1), 0x8,
+ uint8_t(Instruction::DUP9),
+ uint8_t(Instruction::XOR),
+ uint8_t(Instruction::AND),
+ uint8_t(Instruction::OR),
+ uint8_t(Instruction::SUB),
+ uint8_t(Instruction::ADD),
+ uint8_t(Instruction::DUP2),
+ uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::PUSH1), 0x1d,
+ uint8_t(Instruction::JUMPI),
+ uint8_t(Instruction::INVALID),
+ uint8_t(Instruction::JUMPDEST),
+ uint8_t(Instruction::MOD),
+ uint8_t(Instruction::DUP2),
+ uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::ISZERO),
+ uint8_t(Instruction::PUSH1), 0x26,
+ uint8_t(Instruction::JUMPI),
+ uint8_t(Instruction::INVALID),
+ uint8_t(Instruction::JUMPDEST),
+ uint8_t(Instruction::DIV),
+ uint8_t(Instruction::MUL)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -369,13 +370,13 @@ BOOST_AUTO_TEST_CASE(unary_operators)
)";
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}});
- bytes expectation({byte(Instruction::PUSH1), 0x2,
- byte(Instruction::DUP2),
- byte(Instruction::PUSH1), 0x0,
- byte(Instruction::SUB),
- byte(Instruction::NOT),
- byte(Instruction::EQ),
- byte(Instruction::ISZERO)});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x2,
+ uint8_t(Instruction::DUP2),
+ uint8_t(Instruction::PUSH1), 0x0,
+ uint8_t(Instruction::SUB),
+ uint8_t(Instruction::NOT),
+ uint8_t(Instruction::EQ),
+ uint8_t(Instruction::ISZERO)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -383,53 +384,53 @@ BOOST_AUTO_TEST_CASE(unary_inc_dec)
{
char const* sourceCode = R"(
contract test {
- function f(uint a) returns (uint x) { x = --a ^ (a-- ^ (++a ^ a++)); }
+ function f(uint a) public returns (uint x) { x = --a ^ (a-- ^ (++a ^ a++)); }
}
)";
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "x"}});
// Stack: a, x
- bytes expectation({byte(Instruction::DUP2),
- byte(Instruction::DUP1),
- byte(Instruction::PUSH1), 0x1,
- byte(Instruction::ADD),
+ bytes expectation({uint8_t(Instruction::DUP2),
+ uint8_t(Instruction::DUP1),
+ uint8_t(Instruction::PUSH1), 0x1,
+ uint8_t(Instruction::ADD),
// Stack here: a x a (a+1)
- byte(Instruction::SWAP3),
- byte(Instruction::POP), // first ++
+ uint8_t(Instruction::SWAP3),
+ uint8_t(Instruction::POP), // first ++
// Stack here: (a+1) x a
- byte(Instruction::DUP3),
- byte(Instruction::PUSH1), 0x1,
- byte(Instruction::ADD),
+ uint8_t(Instruction::DUP3),
+ uint8_t(Instruction::PUSH1), 0x1,
+ uint8_t(Instruction::ADD),
// Stack here: (a+1) x a (a+2)
- byte(Instruction::SWAP3),
- byte(Instruction::POP),
+ uint8_t(Instruction::SWAP3),
+ uint8_t(Instruction::POP),
// Stack here: (a+2) x a
- byte(Instruction::DUP3), // second ++
- byte(Instruction::XOR),
+ uint8_t(Instruction::DUP3), // second ++
+ uint8_t(Instruction::XOR),
// Stack here: (a+2) x a^(a+2)
- byte(Instruction::DUP3),
- byte(Instruction::DUP1),
- byte(Instruction::PUSH1), 0x1,
- byte(Instruction::SWAP1),
- byte(Instruction::SUB),
+ uint8_t(Instruction::DUP3),
+ uint8_t(Instruction::DUP1),
+ uint8_t(Instruction::PUSH1), 0x1,
+ uint8_t(Instruction::SWAP1),
+ uint8_t(Instruction::SUB),
// Stack here: (a+2) x a^(a+2) (a+2) (a+1)
- byte(Instruction::SWAP4),
- byte(Instruction::POP), // first --
- byte(Instruction::XOR),
+ uint8_t(Instruction::SWAP4),
+ uint8_t(Instruction::POP), // first --
+ uint8_t(Instruction::XOR),
// Stack here: (a+1) x a^(a+2)^(a+2)
- byte(Instruction::DUP3),
- byte(Instruction::PUSH1), 0x1,
- byte(Instruction::SWAP1),
- byte(Instruction::SUB),
+ uint8_t(Instruction::DUP3),
+ uint8_t(Instruction::PUSH1), 0x1,
+ uint8_t(Instruction::SWAP1),
+ uint8_t(Instruction::SUB),
// Stack here: (a+1) x a^(a+2)^(a+2) a
- byte(Instruction::SWAP3),
- byte(Instruction::POP), // second ++
+ uint8_t(Instruction::SWAP3),
+ uint8_t(Instruction::POP), // second ++
// Stack here: a x a^(a+2)^(a+2)
- byte(Instruction::DUP3), // will change
- byte(Instruction::XOR),
- byte(Instruction::SWAP1),
- byte(Instruction::POP),
- byte(Instruction::DUP1)});
+ uint8_t(Instruction::DUP3), // will change
+ uint8_t(Instruction::XOR),
+ uint8_t(Instruction::SWAP1),
+ uint8_t(Instruction::POP),
+ uint8_t(Instruction::DUP1)});
// Stack here: a x a^(a+2)^(a+2)^a
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -444,16 +445,16 @@ BOOST_AUTO_TEST_CASE(assignment)
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "b"}});
// Stack: a, b
- bytes expectation({byte(Instruction::PUSH1), 0x2,
- byte(Instruction::DUP2),
- byte(Instruction::DUP4),
- byte(Instruction::ADD),
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x2,
+ uint8_t(Instruction::DUP2),
+ uint8_t(Instruction::DUP4),
+ uint8_t(Instruction::ADD),
// Stack here: a b 2 a+b
- byte(Instruction::SWAP3),
- byte(Instruction::POP),
- byte(Instruction::DUP3),
+ uint8_t(Instruction::SWAP3),
+ uint8_t(Instruction::POP),
+ uint8_t(Instruction::DUP3),
// Stack here: a+b b 2 a+b
- byte(Instruction::MUL)});
+ uint8_t(Instruction::MUL)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -466,7 +467,7 @@ BOOST_AUTO_TEST_CASE(negative_literals_8bits)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation(bytes({byte(Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x80));
+ bytes expectation(bytes({uint8_t(Instruction::PUSH32)}) + bytes(31, 0xff) + bytes(1, 0x80));
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -479,7 +480,7 @@ BOOST_AUTO_TEST_CASE(negative_literals_16bits)
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation(bytes({byte(Instruction::PUSH32)}) + bytes(30, 0xff) + bytes{0xf5, 0x43});
+ bytes expectation(bytes({uint8_t(Instruction::PUSH32)}) + bytes(30, 0xff) + bytes{0xf5, 0x43});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -489,12 +490,12 @@ BOOST_AUTO_TEST_CASE(intermediately_overflowing_literals)
// have been applied
char const* sourceCode = R"(
contract test {
- function f() { var x = (0xffffffffffffffffffffffffffffffffffffffff * 0xffffffffffffffffffffffffff01) & 0xbf; }
+ function f() { uint8 x = (0x00ffffffffffffffffffffffffffffffffffffffff * 0xffffffffffffffffffffffffff01) & 0xbf; }
}
)";
bytes code = compileFirstExpression(sourceCode);
- bytes expectation(bytes({byte(Instruction::PUSH1), 0xbf}));
+ bytes expectation(bytes({uint8_t(Instruction::PUSH1), 0xbf}));
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -508,13 +509,13 @@ BOOST_AUTO_TEST_CASE(blockhash)
}
)";
- auto blockhashFun = make_shared<FunctionType>(strings{"uint256"}, strings{"bytes32"},
+ auto blockhashFun = make_shared<FunctionType>(strings{"uint256"}, strings{"bytes32"},
FunctionType::Kind::BlockHash, false, StateMutability::View);
-
+
bytes code = compileFirstExpression(sourceCode, {}, {}, {make_shared<MagicVariableDeclaration>("blockhash", blockhashFun)});
- bytes expectation({byte(Instruction::PUSH1), 0x03,
- byte(Instruction::BLOCKHASH)});
+ bytes expectation({uint8_t(Instruction::PUSH1), 0x03,
+ uint8_t(Instruction::BLOCKHASH)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
@@ -522,32 +523,17 @@ BOOST_AUTO_TEST_CASE(gas_left)
{
char const* sourceCode = R"(
contract test {
- function f() returns (uint256 val) {
- return msg.gas;
- }
- }
- )";
- bytes code = compileFirstExpression(
- sourceCode, {}, {},
- {make_shared<MagicVariableDeclaration>("msg", make_shared<MagicType>(MagicType::Kind::Message))}
- );
-
- bytes expectation({byte(Instruction::GAS)});
- BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
-
- sourceCode = R"(
- contract test {
- function f() returns (uint256 val) {
+ function f() public returns (uint256 val) {
return gasleft();
}
}
)";
- code = compileFirstExpression(
+ bytes code = compileFirstExpression(
sourceCode, {}, {},
{make_shared<MagicVariableDeclaration>("gasleft", make_shared<FunctionType>(strings(), strings{"uint256"}, FunctionType::Kind::GasLeft))}
);
- expectation = bytes({byte(Instruction::GAS)});
+ bytes expectation = bytes({uint8_t(Instruction::GAS)});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}