diff options
-rw-r--r-- | libsolidity/ast/Types.cpp | 6 | ||||
-rw-r--r-- | libsolidity/interface/ABI.cpp | 4 | ||||
-rw-r--r-- | test/libsolidity/SolidityABIJSON.cpp | 36 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 6 |
4 files changed, 46 insertions, 6 deletions
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 9fdfe632..14b30df8 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1783,6 +1783,8 @@ TypePointer StructType::interfaceType(bool _inLibrary) const if (_inLibrary && location() == DataLocation::Storage) return shared_from_this(); else if (!recursive()) + // TODO this might not be enough, we have to convert all members to + // their interfaceType return copyForLocation(DataLocation::Memory, true); else return TypePointer(); @@ -1805,7 +1807,9 @@ string StructType::signatureInExternalFunction(bool _structsByName) const auto memberTypeStrings = memberTypes | boost::adaptors::transformed([&](TypePointer _t) -> string { solAssert(_t, "Parameter should have external type."); - return _t->signatureInExternalFunction(_structsByName); + auto t = _t->interfaceType(_structsByName); + solAssert(t, ""); + return t->signatureInExternalFunction(_structsByName); }); return "(" + boost::algorithm::join(memberTypeStrings, ",") + ")"; } diff --git a/libsolidity/interface/ABI.cpp b/libsolidity/interface/ABI.cpp index c04de57e..0e28d010 100644 --- a/libsolidity/interface/ABI.cpp +++ b/libsolidity/interface/ABI.cpp @@ -152,7 +152,9 @@ Json::Value ABI::formatType(string const& _name, Type const& _type, bool _forLib for (auto const& member: structType->members(nullptr)) { solAssert(member.type, ""); - ret["type"].append(formatType(member.name, *member.type, _forLibrary)); + auto t = member.type->interfaceType(_forLibrary); + solAssert(t, ""); + ret["type"].append(formatType(member.name, *t, _forLibrary)); } } else diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp index 7f03285d..3de8b732 100644 --- a/test/libsolidity/SolidityABIJSON.cpp +++ b/test/libsolidity/SolidityABIJSON.cpp @@ -980,6 +980,42 @@ BOOST_AUTO_TEST_CASE(return_structs) checkInterface(text, interface); } +BOOST_AUTO_TEST_CASE(return_structs_with_contracts) +{ + char const* text = R"( + contract C { + struct S { C[] x; C y; } + function f() returns (S s, C c) { + } + } + )"; + char const* interface = R"( + [ + { + "constant" : false, + "payable": false, + "inputs": [], + "name": "f", + "outputs" : [{ + "name" : "s", + "type" : [{ + "name" : "x", + "type" : "address[]" + }, { + "name" : "y", + "type" : "address" + }] + }, { + "name" : "c", + "type" : "address" + }], + "type" : "function" + } + ] + )"; + checkInterface(text, interface); +} + BOOST_AUTO_TEST_CASE(event_structs) { char const* text = R"( diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 9dfbea21..dcab8fb0 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -609,7 +609,7 @@ BOOST_AUTO_TEST_CASE(external_structs) struct Nested { X[2][] a; mapping(uint => uint) m; uint y; } struct X { bytes32 x; Test t; Empty[] e; } function f(ActionChoices, uint, Empty) external {} - function g(Nested) external {} + function g(Test, Nested) external {} function h(function(Nested) external returns (uint)[]) external {} function i(Nested[]) external {} } @@ -620,10 +620,8 @@ BOOST_AUTO_TEST_CASE(external_structs) { auto functions = contract->definedFunctions(); BOOST_REQUIRE(!functions.empty()); - for (auto const& f: functions) - cout << f->externalSignature() << endl; BOOST_CHECK_EQUAL("f(uint8,uint256,())", functions[0]->externalSignature()); - BOOST_CHECK_EQUAL("g(((bytes32,address,()[])[2][],uint256))", functions[1]->externalSignature()); + BOOST_CHECK_EQUAL("g(address,((bytes32,address,()[])[2][],uint256))", functions[1]->externalSignature()); BOOST_CHECK_EQUAL("h(function[])", functions[2]->externalSignature()); BOOST_CHECK_EQUAL("i(((bytes32,address,()[])[2][],uint256)[])", functions[3]->externalSignature()); } |