Skip to content

Commit dc44f8a

Browse files
authored
Merge pull request #14550 from ethereum/events-at-file-level
File-level events
2 parents 586a7c5 + b0a986f commit dc44f8a

30 files changed

+536
-6
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
### 0.8.22 (unreleased)
22

33
Language Features:
4+
* Allow defining events at file level.
45

56

67
Compiler Features:

docs/contracts/events.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ Events
99
Solidity events give an abstraction on top of the EVM's logging functionality.
1010
Applications can subscribe and listen to these events through the RPC interface of an Ethereum client.
1111

12-
Events are inheritable members of contracts. When you call them, they cause the
12+
Events can be defined at file level or as inheritable members of contracts (including interfaces and libraries).
13+
When you call them, they cause the
1314
arguments to be stored in the transaction's log - a special data structure
14-
in the blockchain. These logs are associated with the address of the contract,
15+
in the blockchain. These logs are associated with the address of the contract that emitted them,
1516
are incorporated into the blockchain, and stay there as long as a block is
1617
accessible (forever as of now, but this might
1718
change with Serenity). The Log and its event data is not accessible from within

docs/grammar/SolidityParser.g4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ sourceUnit: (
2222
| enumDefinition
2323
| userDefinedValueTypeDefinition
2424
| errorDefinition
25+
| eventDefinition
2526
)* EOF;
2627

2728
//@doc: inline

docs/structure-of-a-contract.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,11 @@ Events are convenience interfaces with the EVM logging facilities.
112112
.. code-block:: solidity
113113
114114
// SPDX-License-Identifier: GPL-3.0
115-
pragma solidity >=0.4.21 <0.9.0;
115+
pragma solidity ^0.8.22;
116116
117-
contract SimpleAuction {
118-
event HighestBidIncreased(address bidder, uint amount); // Event
117+
event HighestBidIncreased(address bidder, uint amount); // Event
119118
119+
contract SimpleAuction {
120120
function bid() public payable {
121121
// ...
122122
emit HighestBidIncreased(msg.sender, msg.value); // Triggering event

libsolidity/parsing/Parser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ ASTPointer<SourceUnit> Parser::parse(CharStream& _charStream)
131131
case Token::Function:
132132
nodes.push_back(parseFunctionDefinition(true));
133133
break;
134+
case Token::Event:
135+
nodes.push_back(parseEventDefinition());
136+
break;
134137
default:
135138
if (
136139
// Workaround because `error` is not a keyword.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
event Event();
2+
event Event(uint);
3+
4+
event UnusedEvent();
5+
6+
function f() {
7+
emit Event();
8+
}
9+
10+
contract C {
11+
function c_main() public {
12+
emit Event(42);
13+
f();
14+
}
15+
}
16+
17+
contract D is C {
18+
event Event(string);
19+
20+
function d_main() public {
21+
emit Event("abc");
22+
}
23+
}
24+
// ----
25+
// :C
26+
// [
27+
// {
28+
// "anonymous": false,
29+
// "inputs": [],
30+
// "name": "Event",
31+
// "type": "event"
32+
// },
33+
// {
34+
// "anonymous": false,
35+
// "inputs":
36+
// [
37+
// {
38+
// "indexed": false,
39+
// "internalType": "uint256",
40+
// "name": "",
41+
// "type": "uint256"
42+
// }
43+
// ],
44+
// "name": "Event",
45+
// "type": "event"
46+
// },
47+
// {
48+
// "inputs": [],
49+
// "name": "c_main",
50+
// "outputs": [],
51+
// "stateMutability": "nonpayable",
52+
// "type": "function"
53+
// }
54+
// ]
55+
//
56+
//
57+
// :D
58+
// [
59+
// {
60+
// "anonymous": false,
61+
// "inputs": [],
62+
// "name": "Event",
63+
// "type": "event"
64+
// },
65+
// {
66+
// "anonymous": false,
67+
// "inputs":
68+
// [
69+
// {
70+
// "indexed": false,
71+
// "internalType": "uint256",
72+
// "name": "",
73+
// "type": "uint256"
74+
// }
75+
// ],
76+
// "name": "Event",
77+
// "type": "event"
78+
// },
79+
// {
80+
// "anonymous": false,
81+
// "inputs":
82+
// [
83+
// {
84+
// "indexed": false,
85+
// "internalType": "string",
86+
// "name": "",
87+
// "type": "string"
88+
// }
89+
// ],
90+
// "name": "Event",
91+
// "type": "event"
92+
// },
93+
// {
94+
// "inputs": [],
95+
// "name": "c_main",
96+
// "outputs": [],
97+
// "stateMutability": "nonpayable",
98+
// "type": "function"
99+
// },
100+
// {
101+
// "inputs": [],
102+
// "name": "d_main",
103+
// "outputs": [],
104+
// "stateMutability": "nonpayable",
105+
// "type": "function"
106+
// }
107+
// ]

test/libsolidity/SemanticTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ std::optional<AnnotatedEventSignature> SemanticTest::matchEvent(util::h256 const
274274
for (std::string& contractName: m_compiler.contractNames())
275275
{
276276
ContractDefinition const& contract = m_compiler.contractDefinition(contractName);
277-
for (EventDefinition const* event: contract.events())
277+
for (EventDefinition const* event: contract.events() + contract.usedInterfaceEvents())
278278
{
279279
FunctionTypePointer eventFunctionType = event->functionType(true);
280280
if (!event->isAnonymous() && keccak256(eventFunctionType->externalSignature()) == hash)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/// @notice Userdoc for file-level event E.
2+
/// @dev Devdoc for file-level E.
3+
event E();
4+
5+
contract C {
6+
function f() public {
7+
emit E();
8+
}
9+
}
10+
11+
// ----
12+
// ----
13+
// :C devdoc
14+
// {
15+
// "events":
16+
// {
17+
// "E()":
18+
// {
19+
// "details": "Devdoc for file-level E."
20+
// }
21+
// },
22+
// "kind": "dev",
23+
// "methods": {},
24+
// "version": 1
25+
// }
26+
//
27+
// :C userdoc
28+
// {
29+
// "events":
30+
// {
31+
// "E()":
32+
// {
33+
// "notice": "Userdoc for file-level event E."
34+
// }
35+
// },
36+
// "kind": "user",
37+
// "methods": {},
38+
// "version": 1
39+
// }
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/// @notice Userdoc for file-level event E.
2+
/// @dev Devdoc for file-level E.
3+
event E();
4+
5+
contract C {
6+
function f() public {
7+
emit E();
8+
}
9+
}
10+
11+
contract D is C {}
12+
13+
// ----
14+
// ----
15+
// :C devdoc
16+
// {
17+
// "events":
18+
// {
19+
// "E()":
20+
// {
21+
// "details": "Devdoc for file-level E."
22+
// }
23+
// },
24+
// "kind": "dev",
25+
// "methods": {},
26+
// "version": 1
27+
// }
28+
//
29+
// :C userdoc
30+
// {
31+
// "events":
32+
// {
33+
// "E()":
34+
// {
35+
// "notice": "Userdoc for file-level event E."
36+
// }
37+
// },
38+
// "kind": "user",
39+
// "methods": {},
40+
// "version": 1
41+
// }
42+
//
43+
// :D devdoc
44+
// {
45+
// "events":
46+
// {
47+
// "E()":
48+
// {
49+
// "details": "Devdoc for file-level E."
50+
// }
51+
// },
52+
// "kind": "dev",
53+
// "methods": {},
54+
// "version": 1
55+
// }
56+
//
57+
// :D userdoc
58+
// {
59+
// "events":
60+
// {
61+
// "E()":
62+
// {
63+
// "notice": "Userdoc for file-level event E."
64+
// }
65+
// },
66+
// "kind": "user",
67+
// "methods": {},
68+
// "version": 1
69+
// }
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/// @notice Userdoc for file-level event E.
2+
/// @dev Devdoc for file-level E.
3+
event E();
4+
5+
contract F {
6+
/// @notice Userdoc for event F.E.
7+
/// @dev Devdoc for event F.E.
8+
event E();
9+
}
10+
11+
contract C {
12+
function f() public {
13+
emit E();
14+
emit F.E();
15+
}
16+
}
17+
18+
// ----
19+
// ----
20+
// :C devdoc
21+
// {
22+
// "kind": "dev",
23+
// "methods": {},
24+
// "version": 1
25+
// }
26+
//
27+
// :C userdoc
28+
// {
29+
// "kind": "user",
30+
// "methods": {},
31+
// "version": 1
32+
// }
33+
//
34+
// :F devdoc
35+
// {
36+
// "events":
37+
// {
38+
// "E()":
39+
// {
40+
// "details": "Devdoc for event F.E."
41+
// }
42+
// },
43+
// "kind": "dev",
44+
// "methods": {},
45+
// "version": 1
46+
// }
47+
//
48+
// :F userdoc
49+
// {
50+
// "events":
51+
// {
52+
// "E()":
53+
// {
54+
// "notice": "Userdoc for event F.E."
55+
// }
56+
// },
57+
// "kind": "user",
58+
// "methods": {},
59+
// "version": 1
60+
// }

0 commit comments

Comments
 (0)