diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index 1ca5d9160..8cb901a39 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -493,9 +493,18 @@ dev::bytes const& CodeModel::getStdContractCode(const QString& _contractName, co return m_compiledContracts.at(_contractName); } +void CodeModel::retrieveSubType(SolidityType& _wrapperType, dev::solidity::Type const* _type) +{ + if (_type->getCategory() == Type::Category::Array) + { + ArrayType const* arrayType = dynamic_cast(_type); + _wrapperType.baseType = std::make_shared(nodeType(arrayType->getBaseType().get())); + } +} + SolidityType CodeModel::nodeType(dev::solidity::Type const* _type) { - SolidityType r { SolidityType::Type::UnsignedInteger, 32, 1, false, false, QString::fromStdString(_type->toString()), std::vector(), std::vector() }; + SolidityType r { SolidityType::Type::UnsignedInteger, 32, 1, false, false, QString::fromStdString(_type->toString()), std::vector(), std::vector(), nullptr }; if (!_type) return r; switch (_type->getCategory()) @@ -536,6 +545,7 @@ SolidityType CodeModel::nodeType(dev::solidity::Type const* _type) r.count = static_cast(array->getLength()); r.dynamicSize = _type->isDynamicallySized(); r.array = true; + retrieveSubType(r, _type); } break; case Type::Category::Enum: diff --git a/mix/CodeModel.h b/mix/CodeModel.h index b9d06341d..7841c7142 100644 --- a/mix/CodeModel.h +++ b/mix/CodeModel.h @@ -224,6 +224,8 @@ public: Q_INVOKABLE void unregisterContractSrc(QString const& _documentId); /// Convert solidity type info to mix type static SolidityType nodeType(dev::solidity::Type const* _type); + /// Retrieve subtype + static void retrieveSubType(SolidityType& _wrapperType, dev::solidity::Type const* _type); /// Check if given location belongs to contract or function bool isContractOrFunctionLocation(dev::SourceLocation const& _location); /// Get funciton name by location diff --git a/mix/ContractCallDataEncoder.cpp b/mix/ContractCallDataEncoder.cpp index 62cc39a04..da21869e4 100644 --- a/mix/ContractCallDataEncoder.cpp +++ b/mix/ContractCallDataEncoder.cpp @@ -37,24 +37,6 @@ using namespace dev; using namespace dev::solidity; using namespace dev::mix; -static QList extractDimension(QString const& _type) -{ - QList dim; - QRegExp dimExtract("(\\[[^\\]]*\\])"); - int pos = dimExtract.indexIn(_type); - while (pos != -1) - { - QString d = dimExtract.cap(0); - pos += d.length(); - pos = dimExtract.indexIn(_type, pos); - if (d == "[]") - dim.push_front(-1); - else - dim.push_front(d.replace("[", "").replace("]", "").toInt()); - } - return dim; -} - bytes ContractCallDataEncoder::encodedData() { bytes r(m_encodedData); @@ -81,25 +63,24 @@ void ContractCallDataEncoder::encode(QFunctionDefinition const* _function) m_encodedData.insert(m_encodedData.end(), hash.begin(), hash.end()); } -void ContractCallDataEncoder::encodeArray(QJsonArray const& _array, QList _dim, SolidityType const& _type, bytes& _content) +void ContractCallDataEncoder::encodeArray(QJsonArray const& _array, SolidityType const& _type, bytes& _content) { size_t offsetStart = _content.size(); - if (_dim[0] == -1) + if (_type.dynamicSize) { bytes count = bytes(32); toBigEndian((u256)_array.size(), count); _content += count; //reserved space for count } - _dim.pop_front(); int k = 0; for (QJsonValue const& c: _array) { if (c.isArray()) { - if (_dim[0] == -1) + if (_type.baseType->dynamicSize) m_dynamicOffsetMap.push_back(std::make_pair(m_dynamicData.size() + offsetStart + 32 + k * 32, m_dynamicData.size() + _content.size())); - encodeArray(c.toArray(), _dim, _type, _content); + encodeArray(c.toArray(), *_type.baseType, _content); } else { @@ -128,16 +109,15 @@ void ContractCallDataEncoder::encode(QVariant const& _data, SolidityType const& } else if (_type.array) { - QList dim = extractDimension(_type. name); bytes content; size_t size = m_encodedData.size(); - if (dim.front() == -1) + if (_type.dynamicSize) { m_encodedData += bytes(32); // reserve space for offset m_staticOffsetMap.push_back(std::make_pair(size, m_dynamicData.size())); } QJsonDocument jsonDoc = QJsonDocument::fromJson(_data.toString().toUtf8()); - encodeArray(jsonDoc.array(), dim, _type, content); + encodeArray(jsonDoc.array(), _type, content); if (!_type.dynamicSize) m_encodedData.insert(m_encodedData.end(), content.begin(), content.end()); diff --git a/mix/ContractCallDataEncoder.h b/mix/ContractCallDataEncoder.h index e29cb92e0..be11a5772 100644 --- a/mix/ContractCallDataEncoder.h +++ b/mix/ContractCallDataEncoder.h @@ -71,7 +71,7 @@ private: QString toString(bool _b); QString toString(dev::bytes const& _b); bool asString(dev::bytes const& _b, QString& _str); - void encodeArray(QJsonArray const& _array, QList _dim, SolidityType const& _type, bytes& _content); + void encodeArray(QJsonArray const& _array, SolidityType const& _type, bytes& _content); QString toChar(dev::bytes const& _b); private: diff --git a/mix/SolidityType.h b/mix/SolidityType.h index 75f47e7fa..13f5c2ecd 100644 --- a/mix/SolidityType.h +++ b/mix/SolidityType.h @@ -57,6 +57,7 @@ struct SolidityType QString name; std::vector members; //for struct std::vector enumNames; //for enum + std::shared_ptr baseType; }; struct SolidityDeclaration