Allow event definitions at file level

This commit is contained in:
Kamil Śliwak
2023-09-15 14:47:40 +02:00
parent 020b59680e
commit b0a986ffff
30 changed files with 536 additions and 6 deletions
@@ -0,0 +1,107 @@
event Event();
event Event(uint);
event UnusedEvent();
function f() {
emit Event();
}
contract C {
function c_main() public {
emit Event(42);
f();
}
}
contract D is C {
event Event(string);
function d_main() public {
emit Event("abc");
}
}
// ----
// :C
// [
// {
// "anonymous": false,
// "inputs": [],
// "name": "Event",
// "type": "event"
// },
// {
// "anonymous": false,
// "inputs":
// [
// {
// "indexed": false,
// "internalType": "uint256",
// "name": "",
// "type": "uint256"
// }
// ],
// "name": "Event",
// "type": "event"
// },
// {
// "inputs": [],
// "name": "c_main",
// "outputs": [],
// "stateMutability": "nonpayable",
// "type": "function"
// }
// ]
//
//
// :D
// [
// {
// "anonymous": false,
// "inputs": [],
// "name": "Event",
// "type": "event"
// },
// {
// "anonymous": false,
// "inputs":
// [
// {
// "indexed": false,
// "internalType": "uint256",
// "name": "",
// "type": "uint256"
// }
// ],
// "name": "Event",
// "type": "event"
// },
// {
// "anonymous": false,
// "inputs":
// [
// {
// "indexed": false,
// "internalType": "string",
// "name": "",
// "type": "string"
// }
// ],
// "name": "Event",
// "type": "event"
// },
// {
// "inputs": [],
// "name": "c_main",
// "outputs": [],
// "stateMutability": "nonpayable",
// "type": "function"
// },
// {
// "inputs": [],
// "name": "d_main",
// "outputs": [],
// "stateMutability": "nonpayable",
// "type": "function"
// }
// ]
+1 -1
View File
@@ -274,7 +274,7 @@ std::optional<AnnotatedEventSignature> SemanticTest::matchEvent(util::h256 const
for (std::string& contractName: m_compiler.contractNames())
{
ContractDefinition const& contract = m_compiler.contractDefinition(contractName);
for (EventDefinition const* event: contract.events())
for (EventDefinition const* event: contract.events() + contract.usedInterfaceEvents())
{
FunctionTypePointer eventFunctionType = event->functionType(true);
if (!event->isAnonymous() && keccak256(eventFunctionType->externalSignature()) == hash)
@@ -0,0 +1,39 @@
/// @notice Userdoc for file-level event E.
/// @dev Devdoc for file-level E.
event E();
contract C {
function f() public {
emit E();
}
}
// ----
// ----
// :C devdoc
// {
// "events":
// {
// "E()":
// {
// "details": "Devdoc for file-level E."
// }
// },
// "kind": "dev",
// "methods": {},
// "version": 1
// }
//
// :C userdoc
// {
// "events":
// {
// "E()":
// {
// "notice": "Userdoc for file-level event E."
// }
// },
// "kind": "user",
// "methods": {},
// "version": 1
// }
@@ -0,0 +1,69 @@
/// @notice Userdoc for file-level event E.
/// @dev Devdoc for file-level E.
event E();
contract C {
function f() public {
emit E();
}
}
contract D is C {}
// ----
// ----
// :C devdoc
// {
// "events":
// {
// "E()":
// {
// "details": "Devdoc for file-level E."
// }
// },
// "kind": "dev",
// "methods": {},
// "version": 1
// }
//
// :C userdoc
// {
// "events":
// {
// "E()":
// {
// "notice": "Userdoc for file-level event E."
// }
// },
// "kind": "user",
// "methods": {},
// "version": 1
// }
//
// :D devdoc
// {
// "events":
// {
// "E()":
// {
// "details": "Devdoc for file-level E."
// }
// },
// "kind": "dev",
// "methods": {},
// "version": 1
// }
//
// :D userdoc
// {
// "events":
// {
// "E()":
// {
// "notice": "Userdoc for file-level event E."
// }
// },
// "kind": "user",
// "methods": {},
// "version": 1
// }
@@ -0,0 +1,60 @@
/// @notice Userdoc for file-level event E.
/// @dev Devdoc for file-level E.
event E();
contract F {
/// @notice Userdoc for event F.E.
/// @dev Devdoc for event F.E.
event E();
}
contract C {
function f() public {
emit E();
emit F.E();
}
}
// ----
// ----
// :C devdoc
// {
// "kind": "dev",
// "methods": {},
// "version": 1
// }
//
// :C userdoc
// {
// "kind": "user",
// "methods": {},
// "version": 1
// }
//
// :F devdoc
// {
// "events":
// {
// "E()":
// {
// "details": "Devdoc for event F.E."
// }
// },
// "kind": "dev",
// "methods": {},
// "version": 1
// }
//
// :F userdoc
// {
// "events":
// {
// "E()":
// {
// "notice": "Userdoc for event F.E."
// }
// },
// "kind": "user",
// "methods": {},
// "version": 1
// }
@@ -0,0 +1,21 @@
/// @notice Userdoc for file-level event E.
/// @dev Devdoc for file-level E.
event E();
contract C {}
// ----
// ----
// :C devdoc
// {
// "kind": "dev",
// "methods": {},
// "version": 1
// }
//
// :C userdoc
// {
// "kind": "user",
// "methods": {},
// "version": 1
// }
@@ -0,0 +1,10 @@
event Deposit(address indexed _from, bytes32 indexed _id, uint _value);
contract ClientReceipt {
function deposit(bytes32 _id) public payable {
emit Deposit(msg.sender, _id, msg.value);
}
}
// ----
// deposit(bytes32), 18 wei: 0x1234 ->
// ~ emit Deposit(address,bytes32,uint256): #0x1212121212121212121212121212120000000012, #0x1234, 0x12
@@ -0,0 +1,15 @@
event E();
library L {
event E();
}
contract C {
function main() external pure returns (bytes32, bytes32) {
assert(E.selector == L.E.selector);
return (E.selector, L.E.selector);
}
}
// ----
// main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028
@@ -0,0 +1,38 @@
event E();
library L1 {
event E(string);
}
library L2 {
event E();
}
library K {
function main() internal pure returns (bytes32, bytes32, bytes32) {
// Here E is the global event.
assert(E.selector != L1.E.selector);
assert(E.selector == L2.E.selector);
return (E.selector, L1.E.selector, L2.E.selector);
}
}
contract C {
event E(string);
function main() external pure returns (bytes32, bytes32, bytes32) {
// Here E is the local event.
assert(E.selector == L1.E.selector);
assert(E.selector != L2.E.selector);
return (E.selector, L1.E.selector, L2.E.selector);
}
function k_main() external pure returns (bytes32, bytes32, bytes32) {
return K.main();
}
}
// ----
// main() -> 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028
// k_main() -> 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028, 0x3e9992c940c54ea252d3a34557cc3d3014281525c43d694f89d5f3dfd820b07d, 0x92bbf6e823a631f3c8e09b1c8df90f378fb56f7fbc9701827e1ff8aad7f6a028
@@ -0,0 +1,32 @@
event Deposit();
event Deposit(address _addr);
event Deposit(address _addr, uint _amount);
event Deposit(address _addr, bool _flag);
contract ClientReceipt {
function deposit() public returns (uint) {
emit Deposit();
return 1;
}
function deposit(address _addr) public returns (uint) {
emit Deposit(_addr);
return 2;
}
function deposit(address _addr, uint _amount) public returns (uint) {
emit Deposit(_addr, _amount);
return 3;
}
function deposit(address _addr, bool _flag) public returns (uint) {
emit Deposit(_addr, _flag);
return 4;
}
}
// ----
// deposit() -> 1
// ~ emit Deposit()
// deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988 -> 2
// ~ emit Deposit(address): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988
// deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 100 -> 3
// ~ emit Deposit(address,uint256): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, 0x64
// deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false -> 4
// ~ emit Deposit(address,bool): 0x5082a85c489be6aa0f2e6693bf09cc1bbd35e988, false
@@ -0,0 +1,8 @@
==== Source: M.sol ====
event E();
==== Source: A.sol ====
import "M.sol" as M;
function f() {
emit M.E();
}
@@ -0,0 +1,7 @@
event E();
contract C {
function f() public {
emit E();
}
}
@@ -0,0 +1,7 @@
event E();
contract C {
function f() external pure returns (bytes32) {
return E.selector;
}
}
@@ -0,0 +1,11 @@
event E1();
event E2(uint);
event E3(uint, string indexed, bytes, bool);
event E4(int, int, int) anonymous;
function f() {
emit E1();
emit E2(1);
emit E3(1, "abc", "abc", true);
emit E4(1, 2, 3);
}
@@ -0,0 +1,4 @@
event E();
event E();
// ----
// DeclarationError 5883: (0-10): Event with same name and parameter types defined twice.
@@ -0,0 +1,8 @@
==== Source: A.sol ====
event E();
==== Source: B.sol ====
import "A.sol";
event E();
// ----
// DeclarationError 5883: (B.sol:17-27): Event with same name and parameter types defined twice.
@@ -0,0 +1,12 @@
==== Source: A.sol ====
event EA();
==== Source: B.sol ====
event EB();
==== Source: C.sol ====
import "A.sol";
import {EB} from "B.sol";
function f() {
emit EA();
emit EB();
}
@@ -0,0 +1,11 @@
event E();
event E(uint);
event E(uint, string indexed, bytes, bool);
event E(int, int, int) anonymous;
function f() {
emit E();
emit E(1);
emit E(1, "abc", "abc", true);
emit E(1, 2, 3);
}
@@ -0,0 +1,13 @@
event E();
contract C {
event E(uint);
function f() public {
emit E();
emit E(1);
}
}
// ----
// Warning 2519: (29-43): This declaration shadows an existing declaration.
// TypeError 6160: (84-87): Wrong argument count for function call: 0 arguments given but expected 1.
@@ -0,0 +1,17 @@
event E();
contract C {
event E();
}
library L {
event E();
}
interface I {
event E();
}
// ----
// Warning 2519: (29-39): This declaration shadows an existing declaration.
// Warning 2519: (59-69): This declaration shadows an existing declaration.
// Warning 2519: (91-101): This declaration shadows an existing declaration.
@@ -0,0 +1,17 @@
event E();
contract C {
event E() anonymous;
}
library L {
event E() anonymous;
}
interface I {
event E() anonymous;
}
// ----
// Warning 2519: (29-49): This declaration shadows an existing declaration.
// Warning 2519: (69-89): This declaration shadows an existing declaration.
// Warning 2519: (111-131): This declaration shadows an existing declaration.
@@ -0,0 +1,4 @@
event E();
contract E {}
// ----
// DeclarationError 2333: (11-24): Identifier already declared.
@@ -0,0 +1,4 @@
event E();
error E();
// ----
// DeclarationError 2333: (11-21): Identifier already declared.
@@ -0,0 +1,6 @@
event E();
type T is uint;
using {E} for T;
// ----
// TypeError 8187: (35-36): Expected function name.
@@ -0,0 +1,4 @@
// Exception for the illegal name list. External interface events
event this();
event super();
event _();