|
@ -47,7 +47,7 @@ |
|
|
using namespace dev::mix; |
|
|
using namespace dev::mix; |
|
|
|
|
|
|
|
|
const std::set<std::string> c_predefinedContracts = |
|
|
const std::set<std::string> c_predefinedContracts = |
|
|
{ "Config", "Coin", "CoinReg", "coin", "service", "owned", "mortal", "NameReg", "named", "std", "configUser" }; |
|
|
{ "Config", "Coin", "CoinReg", "coin", "service", "owned", "mortal", "NameReg", "named", "std", "configUser" }; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace |
|
|
namespace |
|
@ -59,7 +59,7 @@ class CollectLocalsVisitor: public ASTConstVisitor |
|
|
{ |
|
|
{ |
|
|
public: |
|
|
public: |
|
|
CollectLocalsVisitor(QHash<LocationPair, SolidityDeclaration>* _locals): |
|
|
CollectLocalsVisitor(QHash<LocationPair, SolidityDeclaration>* _locals): |
|
|
m_locals(_locals), m_functionScope(false) {} |
|
|
m_locals(_locals), m_functionScope(false) {} |
|
|
|
|
|
|
|
|
private: |
|
|
private: |
|
|
LocationPair nodeLocation(ASTNode const& _node) |
|
|
LocationPair nodeLocation(ASTNode const& _node) |
|
@ -99,7 +99,7 @@ class CollectLocationsVisitor: public ASTConstVisitor |
|
|
{ |
|
|
{ |
|
|
public: |
|
|
public: |
|
|
CollectLocationsVisitor(SourceMap* _sourceMap): |
|
|
CollectLocationsVisitor(SourceMap* _sourceMap): |
|
|
m_sourceMap(_sourceMap) {} |
|
|
m_sourceMap(_sourceMap) {} |
|
|
|
|
|
|
|
|
private: |
|
|
private: |
|
|
LocationPair nodeLocation(ASTNode const& _node) |
|
|
LocationPair nodeLocation(ASTNode const& _node) |
|
@ -313,24 +313,47 @@ void CodeModel::runCompilationJob(int _jobId) |
|
|
} |
|
|
} |
|
|
catch (dev::Exception const& _exception) |
|
|
catch (dev::Exception const& _exception) |
|
|
{ |
|
|
{ |
|
|
std::ostringstream error; |
|
|
std::stringstream error; |
|
|
solidity::SourceReferenceFormatter::printExceptionInformation(error, _exception, "Error", cs); |
|
|
solidity::SourceReferenceFormatter::printExceptionInformation(error, _exception, "Error", cs); |
|
|
QString message = QString::fromStdString(error.str()); |
|
|
QString message = QString::fromStdString(error.str()); |
|
|
QString sourceName; |
|
|
QVariantMap firstLocation; |
|
|
if (SourceLocation const* location = boost::get_error_info<solidity::errinfo_sourceLocation>(_exception)) |
|
|
QVariantList secondLocations; |
|
|
|
|
|
if (SourceLocation const* first = boost::get_error_info<solidity::errinfo_sourceLocation>(_exception)) |
|
|
|
|
|
firstLocation = resolveCompilationErrorLocation(cs, *first); |
|
|
|
|
|
if (SecondarySourceLocation const* second = boost::get_error_info<solidity::errinfo_secondarySourceLocation>(_exception)) |
|
|
{ |
|
|
{ |
|
|
if (location->sourceName) |
|
|
for (auto const& c: second->infos) |
|
|
sourceName = QString::fromStdString(*location->sourceName); |
|
|
secondLocations.push_back(resolveCompilationErrorLocation(cs, c.second)); |
|
|
if (!sourceName.isEmpty()) |
|
|
|
|
|
if (CompiledContract* contract = contractByDocumentId(sourceName)) |
|
|
|
|
|
message = message.replace(sourceName, contract->contract()->name()); //substitute the location to match our contract names
|
|
|
|
|
|
} |
|
|
} |
|
|
compilationError(message, sourceName); |
|
|
compilationError(message, firstLocation, secondLocations); |
|
|
} |
|
|
} |
|
|
m_compiling = false; |
|
|
m_compiling = false; |
|
|
emit stateChanged(); |
|
|
emit stateChanged(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
QVariantMap CodeModel::resolveCompilationErrorLocation(CompilerStack const& _compiler, SourceLocation const& _location) |
|
|
|
|
|
{ |
|
|
|
|
|
std::tuple<int, int, int, int> pos = _compiler.positionFromSourceLocation(_location); |
|
|
|
|
|
QVariantMap startError; |
|
|
|
|
|
startError.insert("line", std::get<0>(pos) > 1 ? (std::get<0>(pos) - 1) : 1); |
|
|
|
|
|
startError.insert("column", std::get<1>(pos) > 1 ? (std::get<1>(pos) - 1) : 1); |
|
|
|
|
|
QVariantMap endError; |
|
|
|
|
|
endError.insert("line", std::get<2>(pos) > 1 ? (std::get<2>(pos) - 1) : 1); |
|
|
|
|
|
endError.insert("column", std::get<3>(pos) > 1 ? (std::get<3>(pos) - 1) : 1); |
|
|
|
|
|
QVariantMap error; |
|
|
|
|
|
error.insert("start", startError); |
|
|
|
|
|
error.insert("end", endError); |
|
|
|
|
|
QString sourceName; |
|
|
|
|
|
if (_location.sourceName) |
|
|
|
|
|
sourceName = QString::fromStdString(*_location.sourceName); |
|
|
|
|
|
error.insert("source", sourceName); |
|
|
|
|
|
if (!sourceName.isEmpty()) |
|
|
|
|
|
if (CompiledContract* contract = contractByDocumentId(sourceName)) |
|
|
|
|
|
sourceName = contract->contract()->name(); //substitute the location to match our contract names
|
|
|
|
|
|
error.insert("contractName", sourceName); |
|
|
|
|
|
return error; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
void CodeModel::gasEstimation(solidity::CompilerStack const& _cs) |
|
|
void CodeModel::gasEstimation(solidity::CompilerStack const& _cs) |
|
|
{ |
|
|
{ |
|
|
if (m_gasCostsMaps) |
|
|
if (m_gasCostsMaps) |
|
@ -411,7 +434,7 @@ void CodeModel::collectContracts(dev::solidity::CompilerStack const& _cs, std::v |
|
|
{ |
|
|
{ |
|
|
//make sure there are no other contracts in the same source, otherwise it is not a rename
|
|
|
//make sure there are no other contracts in the same source, otherwise it is not a rename
|
|
|
if (!std::any_of(result.begin(),result.end(), [=](ContractMap::const_iterator::value_type _v) { return _v != contract && _v->documentId() == contract->documentId(); })) |
|
|
if (!std::any_of(result.begin(),result.end(), [=](ContractMap::const_iterator::value_type _v) { return _v != contract && _v->documentId() == contract->documentId(); })) |
|
|
prevContract = c.value(); |
|
|
prevContract = c.value(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
if (prevContract != nullptr && prevContract->contractInterface() != result[name]->contractInterface()) |
|
|
if (prevContract != nullptr && prevContract->contractInterface() != result[name]->contractInterface()) |
|
@ -461,59 +484,59 @@ SolidityType CodeModel::nodeType(dev::solidity::Type const* _type) |
|
|
switch (_type->getCategory()) |
|
|
switch (_type->getCategory()) |
|
|
{ |
|
|
{ |
|
|
case Type::Category::Integer: |
|
|
case Type::Category::Integer: |
|
|
{ |
|
|
{ |
|
|
IntegerType const* it = dynamic_cast<IntegerType const*>(_type); |
|
|
IntegerType const* it = dynamic_cast<IntegerType const*>(_type); |
|
|
r.size = it->getNumBits() / 8; |
|
|
r.size = it->getNumBits() / 8; |
|
|
r.type = it->isAddress() ? SolidityType::Type::Address : it->isSigned() ? SolidityType::Type::SignedInteger : SolidityType::Type::UnsignedInteger; |
|
|
r.type = it->isAddress() ? SolidityType::Type::Address : it->isSigned() ? SolidityType::Type::SignedInteger : SolidityType::Type::UnsignedInteger; |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
case Type::Category::Bool: |
|
|
case Type::Category::Bool: |
|
|
r.type = SolidityType::Type::Bool; |
|
|
r.type = SolidityType::Type::Bool; |
|
|
break; |
|
|
break; |
|
|
case Type::Category::FixedBytes: |
|
|
case Type::Category::FixedBytes: |
|
|
{ |
|
|
{ |
|
|
FixedBytesType const* b = dynamic_cast<FixedBytesType const*>(_type); |
|
|
FixedBytesType const* b = dynamic_cast<FixedBytesType const*>(_type); |
|
|
r.type = SolidityType::Type::Bytes; |
|
|
r.type = SolidityType::Type::Bytes; |
|
|
r.size = static_cast<unsigned>(b->getNumBytes()); |
|
|
r.size = static_cast<unsigned>(b->getNumBytes()); |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
case Type::Category::Contract: |
|
|
case Type::Category::Contract: |
|
|
r.type = SolidityType::Type::Address; |
|
|
r.type = SolidityType::Type::Address; |
|
|
break; |
|
|
break; |
|
|
case Type::Category::Array: |
|
|
case Type::Category::Array: |
|
|
|
|
|
{ |
|
|
|
|
|
ArrayType const* array = dynamic_cast<ArrayType const*>(_type); |
|
|
|
|
|
if (array->isByteArray()) |
|
|
|
|
|
r.type = SolidityType::Type::Bytes; |
|
|
|
|
|
else |
|
|
{ |
|
|
{ |
|
|
ArrayType const* array = dynamic_cast<ArrayType const*>(_type); |
|
|
SolidityType elementType = nodeType(array->getBaseType().get()); |
|
|
if (array->isByteArray()) |
|
|
elementType.name = r.name; |
|
|
r.type = SolidityType::Type::Bytes; |
|
|
r = elementType; |
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
SolidityType elementType = nodeType(array->getBaseType().get()); |
|
|
|
|
|
elementType.name = r.name; |
|
|
|
|
|
r = elementType; |
|
|
|
|
|
} |
|
|
|
|
|
r.count = static_cast<unsigned>(array->getLength()); |
|
|
|
|
|
r.dynamicSize = _type->isDynamicallySized(); |
|
|
|
|
|
r.array = true; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
r.count = static_cast<unsigned>(array->getLength()); |
|
|
|
|
|
r.dynamicSize = _type->isDynamicallySized(); |
|
|
|
|
|
r.array = true; |
|
|
|
|
|
} |
|
|
break; |
|
|
break; |
|
|
case Type::Category::Enum: |
|
|
case Type::Category::Enum: |
|
|
{ |
|
|
{ |
|
|
r.type = SolidityType::Type::Enum; |
|
|
r.type = SolidityType::Type::Enum; |
|
|
EnumType const* e = dynamic_cast<EnumType const*>(_type); |
|
|
EnumType const* e = dynamic_cast<EnumType const*>(_type); |
|
|
for(auto const& enumValue: e->getEnumDefinition().getMembers()) |
|
|
for(auto const& enumValue: e->getEnumDefinition().getMembers()) |
|
|
r.enumNames.push_back(QString::fromStdString(enumValue->getName())); |
|
|
r.enumNames.push_back(QString::fromStdString(enumValue->getName())); |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
case Type::Category::Struct: |
|
|
case Type::Category::Struct: |
|
|
|
|
|
{ |
|
|
|
|
|
r.type = SolidityType::Type::Struct; |
|
|
|
|
|
StructType const* s = dynamic_cast<StructType const*>(_type); |
|
|
|
|
|
for(auto const& structMember: s->getMembers()) |
|
|
{ |
|
|
{ |
|
|
r.type = SolidityType::Type::Struct; |
|
|
auto slotAndOffset = s->getStorageOffsetsOfMember(structMember.name); |
|
|
StructType const* s = dynamic_cast<StructType const*>(_type); |
|
|
r.members.push_back(SolidityDeclaration { QString::fromStdString(structMember.name), nodeType(structMember.type.get()), slotAndOffset.first, slotAndOffset.second }); |
|
|
for(auto const& structMember: s->getMembers()) |
|
|
|
|
|
{ |
|
|
|
|
|
auto slotAndOffset = s->getStorageOffsetsOfMember(structMember.name); |
|
|
|
|
|
r.members.push_back(SolidityDeclaration { QString::fromStdString(structMember.name), nodeType(structMember.type.get()), slotAndOffset.first, slotAndOffset.second }); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
break; |
|
|
break; |
|
|
case Type::Category::Function: |
|
|
case Type::Category::Function: |
|
|
case Type::Category::IntegerConstant: |
|
|
case Type::Category::IntegerConstant: |
|
|