From 7061943d520bbaaa14fbad4cd54e74a248f02456 Mon Sep 17 00:00:00 2001 From: Valery Aligorsky Date: Sat, 28 Aug 2021 11:33:25 +0200 Subject: [PATCH] feat(sol-0.8): add support for errors exports --- lib/antlr/visitors/exportVisitor.ts | 38 +++++++++++++++++++++++++- lib/types.ts | 1 + test/compiled/ContractWithEvents.sol | 12 ++++++++ test/compiled/ContractsWithErrors.sol | 19 +++++++++++++ test/contracts/ContractWithEvents.sol | 11 ++++++++ test/contracts/ContractsWithErrors.sol | 18 ++++++++++++ test/index.spec.ts | 8 ++++++ 7 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 test/compiled/ContractWithEvents.sol create mode 100644 test/compiled/ContractsWithErrors.sol create mode 100644 test/contracts/ContractWithEvents.sol create mode 100644 test/contracts/ContractsWithErrors.sol diff --git a/lib/antlr/visitors/exportVisitor.ts b/lib/antlr/visitors/exportVisitor.ts index ed500df..0328c90 100644 --- a/lib/antlr/visitors/exportVisitor.ts +++ b/lib/antlr/visitors/exportVisitor.ts @@ -6,7 +6,7 @@ import { SolidityParserListener } from '../generated/SolidityParserListener'; import { ContractDefinitionContext, EnumDefinitionContext, - InheritanceSpecifierContext, + ErrorDefinitionContext, InheritanceSpecifierListContext, InterfaceDefinitionContext, LibraryDefinitionContext, @@ -305,4 +305,40 @@ class ExportVisitor implements SolidityParserListener { name: name.text, }); } + + enterErrorDefinition(ctx: ErrorDefinitionContext): void { + if (!(ctx.parent instanceof SourceUnitContext)) { + return; + } + + if (!ctx.stop) { + return; + } + + if (!ctx.children) { + return; + } + + const start = ctx.start.startIndex; + const end = ctx.stop.stopIndex; + const name = ctx.identifier(); + if (!name?.stop) { + return; + } + + const bodyStart = name.stop.stopIndex; + + this.#onVisit({ + start, + end, + abstract: false, + type: ExportType.error, + body: { + start: bodyStart + 1, + end, + }, + is: null, + name: name.text, + }); + } } diff --git a/lib/types.ts b/lib/types.ts index ccc188c..edfb3e7 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -7,6 +7,7 @@ export enum ExportType { struct = 'struct', enum = 'enum', comment = 'comment', + error = 'error', } export interface ExportPluginProcessor { diff --git a/test/compiled/ContractWithEvents.sol b/test/compiled/ContractWithEvents.sol new file mode 100644 index 0000000..0db9c29 --- /dev/null +++ b/test/compiled/ContractWithEvents.sol @@ -0,0 +1,12 @@ +pragma solidity ^0.8.4; + + +// SPDX-License-Identifier: GPL-3.0 +contract SimpleAuction { + event HighestBidIncreased(address bidder, uint amount); // Event + + function bid() public payable { + // ... + emit HighestBidIncreased(msg.sender, msg.value); // Triggering event + } +} diff --git a/test/compiled/ContractsWithErrors.sol b/test/compiled/ContractsWithErrors.sol new file mode 100644 index 0000000..057c44d --- /dev/null +++ b/test/compiled/ContractsWithErrors.sol @@ -0,0 +1,19 @@ +pragma solidity ^0.8.4; + + +// SPDX-License-Identifier: GPL-3.0 +/// Not enough funds for transfer. Requested `requested`, +/// but only `available` available. +error NotEnoughFunds (uint requested, uint available); + +contract Token { + mapping(address => uint) balances; + function transfer(address to, uint amount) public { + uint balance = balances[msg.sender]; + if (balance < amount) + revert NotEnoughFunds(amount, balance); + balances[msg.sender] -= amount; + balances[to] += amount; + // ... + } +} diff --git a/test/contracts/ContractWithEvents.sol b/test/contracts/ContractWithEvents.sol new file mode 100644 index 0000000..12b6c0f --- /dev/null +++ b/test/contracts/ContractWithEvents.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.4; + +contract SimpleAuction { + event HighestBidIncreased(address bidder, uint amount); // Event + + function bid() public payable { + // ... + emit HighestBidIncreased(msg.sender, msg.value); // Triggering event + } +} diff --git a/test/contracts/ContractsWithErrors.sol b/test/contracts/ContractsWithErrors.sol new file mode 100644 index 0000000..40653ca --- /dev/null +++ b/test/contracts/ContractsWithErrors.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.4; + +/// Not enough funds for transfer. Requested `requested`, +/// but only `available` available. +error NotEnoughFunds(uint requested, uint available); + +contract Token { + mapping(address => uint) balances; + function transfer(address to, uint amount) public { + uint balance = balances[msg.sender]; + if (balance < amount) + revert NotEnoughFunds(amount, balance); + balances[msg.sender] -= amount; + balances[to] += amount; + // ... + } +} diff --git a/test/index.spec.ts b/test/index.spec.ts index 57de7c5..1aec753 100644 --- a/test/index.spec.ts +++ b/test/index.spec.ts @@ -112,4 +112,12 @@ describe('Solidity Merger', () => { it('should compile file with checked/unckecked arithmetic operations (0.8 support)', async () => { await testFile('CheckedUnchecked'); }); + + it('should compile file with errors', async () => { + await testFile('ContractsWithErrors'); + }); + + it('should compile file with events', async () => { + await testFile('ContractWithEvents'); + }); });