diff options
Diffstat (limited to 'libsolidity/interface')
-rw-r--r-- | libsolidity/interface/ABI.cpp | 58 | ||||
-rw-r--r-- | libsolidity/interface/ABI.h | 4 |
2 files changed, 53 insertions, 9 deletions
diff --git a/libsolidity/interface/ABI.cpp b/libsolidity/interface/ABI.cpp index 49df843d..7c7496cd 100644 --- a/libsolidity/interface/ABI.cpp +++ b/libsolidity/interface/ABI.cpp @@ -86,12 +86,12 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef) Json::Value params(Json::arrayValue); for (auto const& p: it->parameters()) { - solAssert(!!p->annotation().type->interfaceType(false), ""); + auto type = p->annotation().type->interfaceType(false); + solAssert(type, ""); Json::Value input; - input["name"] = p->name(); - input["type"] = p->annotation().type->interfaceType(false)->canonicalName(false); - input["indexed"] = p->isIndexed(); - params.append(input); + auto param = formatType(p->name(), *type, false); + param["indexed"] = p->isIndexed(); + params.append(param); } event["inputs"] = params; abi.append(event); @@ -111,10 +111,50 @@ Json::Value ABI::formatTypeList( for (unsigned i = 0; i < _names.size(); ++i) { solAssert(_types[i], ""); - Json::Value param; - param["name"] = _names[i]; - param["type"] = _types[i]->canonicalName(_forLibrary); - params.append(param); + params.append(formatType(_names[i], *_types[i], _forLibrary)); } return params; } + +Json::Value ABI::formatType(string const& _name, Type const& _type, bool _forLibrary) +{ + Json::Value ret; + ret["name"] = _name; + if (_type.isValueType() || (_forLibrary && _type.dataStoredIn(DataLocation::Storage))) + ret["type"] = _type.canonicalName(_forLibrary); + else if (ArrayType const* arrayType = dynamic_cast<ArrayType const*>(&_type)) + { + if (arrayType->isByteArray()) + ret["type"] = _type.canonicalName(_forLibrary); + else + { + string suffix; + if (arrayType->isDynamicallySized()) + suffix = "[]"; + else + suffix = string("[") + arrayType->length().str() + "]"; + solAssert(arrayType->baseType(), ""); + Json::Value subtype = formatType("", *arrayType->baseType(), _forLibrary); + if (subtype["type"].isString() && !subtype.isMember("subtype")) + ret["type"] = subtype["type"].asString() + suffix; + else + { + ret["type"] = suffix; + solAssert(!subtype.isMember("subtype"), ""); + ret["subtype"] = subtype["type"]; + } + } + } + else if (StructType const* structType = dynamic_cast<StructType const*>(&_type)) + { + ret["type"] = Json::arrayValue; + for (auto const& member: structType->members(nullptr)) + { + solAssert(member.type, ""); + ret["type"].append(formatType(member.name, *member.type, _forLibrary)); + } + } + else + solAssert(false, "Invalid type."); + return ret; +} diff --git a/libsolidity/interface/ABI.h b/libsolidity/interface/ABI.h index 95b162a9..7e42909b 100644 --- a/libsolidity/interface/ABI.h +++ b/libsolidity/interface/ABI.h @@ -50,6 +50,10 @@ private: std::vector<TypePointer> const& _types, bool _forLibrary ); + /// @returns a Json object with "name", "type" and potentially "subtype" keys, according + /// to the ABI specification. + /// If it is possible to express the type as a single string, it is allowed to return a single string. + static Json::Value formatType(std::string const& _name, Type const& _type, bool _forLibrary); }; } |