diff --git a/libsolidity/interface/ABI.cpp b/libsolidity/interface/ABI.cpp index 960d4270e..c4a2dfe5c 100644 --- a/libsolidity/interface/ABI.cpp +++ b/libsolidity/interface/ABI.cpp @@ -121,6 +121,23 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) abi.emplace(std::move(event)); } + for (ErrorDefinition const* error: _contractDef.interfaceErrors()) + { + Json::Value errorJson; + errorJson["type"] = "error"; + errorJson["name"] = error->name(); + errorJson["inputs"] = Json::arrayValue; + for (auto const& p: error->parameters()) + { + Type const* type = p->annotation().type->interfaceType(false); + solAssert(type, ""); + errorJson["inputs"].append( + formatType(p->name(), *type, *p->annotation().type, false) + ); + } + abi.emplace(move(errorJson)); + } + Json::Value abiJson{Json::arrayValue}; for (auto& f: abi) abiJson.append(std::move(f)); diff --git a/test/libsolidity/ABIJson/errors.sol b/test/libsolidity/ABIJson/errors.sol new file mode 100644 index 000000000..91c76ce6f --- /dev/null +++ b/test/libsolidity/ABIJson/errors.sol @@ -0,0 +1,93 @@ +error FreeError(); +contract X { + error E(uint); + error E2(uint a, uint b); + error E4(uint a, bytes[][] c); + struct S { uint x; } + error E5(S t); + function f() public pure { + revert FreeError(); + } +} +// ---- +// :X +// [ +// { +// "inputs": +// [ +// { +// "internalType": "uint256", +// "name": "", +// "type": "uint256" +// } +// ], +// "name": "E", +// "type": "error" +// }, +// { +// "inputs": +// [ +// { +// "internalType": "uint256", +// "name": "a", +// "type": "uint256" +// }, +// { +// "internalType": "uint256", +// "name": "b", +// "type": "uint256" +// } +// ], +// "name": "E2", +// "type": "error" +// }, +// { +// "inputs": +// [ +// { +// "internalType": "uint256", +// "name": "a", +// "type": "uint256" +// }, +// { +// "internalType": "bytes[][]", +// "name": "c", +// "type": "bytes[][]" +// } +// ], +// "name": "E4", +// "type": "error" +// }, +// { +// "inputs": +// [ +// { +// "components": +// [ +// { +// "internalType": "uint256", +// "name": "x", +// "type": "uint256" +// } +// ], +// "internalType": "struct X.S", +// "name": "t", +// "type": "tuple" +// } +// ], +// "name": "E5", +// "type": "error" +// }, +// { +// "inputs": [], +// "name": "FreeError", +// "type": "error" +// }, +// { +// "inputs": [], +// "name": "f", +// "outputs": [], +// "stateMutability": "pure", +// "type": "function" +// } +// ] diff --git a/test/libsolidity/ABIJson/errors_referenced.sol b/test/libsolidity/ABIJson/errors_referenced.sol new file mode 100644 index 000000000..ecb5b1003 --- /dev/null +++ b/test/libsolidity/ABIJson/errors_referenced.sol @@ -0,0 +1,94 @@ +error E1(); +function f() { + revert E1(); +} +contract C { + // unreferenced but inherited + error E2(); +} +contract D { + // referenced + error E3(uint); +} +contract X is C { + // unreferenced but defined + error E3(); + function g(uint x) public { + if (x == 0) + f(); + else if (x == 2) + revert D.E3(1); + } +} +// ---- +// :C +// [ +// { +// "inputs": [], +// "name": "E2", +// "type": "error" +// } +// ] +// +// +// :D +// [ +// { +// "inputs": +// [ +// { +// "internalType": "uint256", +// "name": "", +// "type": "uint256" +// } +// ], +// "name": "E3", +// "type": "error" +// } +// ] +// +// +// :X +// [ +// { +// "inputs": [], +// "name": "E1", +// "type": "error" +// }, +// { +// "inputs": [], +// "name": "E2", +// "type": "error" +// }, +// { +// "inputs": +// [ +// { +// "internalType": "uint256", +// "name": "", +// "type": "uint256" +// } +// ], +// "name": "E3", +// "type": "error" +// }, +// { +// "inputs": [], +// "name": "E3", +// "type": "error" +// }, +// { +// "inputs": +// [ +// { +// "internalType": "uint256", +// "name": "x", +// "type": "uint256" +// } +// ], +// "name": "g", +// "outputs": [], +// "stateMutability": "nonpayable", +// "type": "function" +// } +// ]