Properly assign source names for AST import.

This commit is contained in:
chriseth 2021-07-01 16:58:01 +02:00
parent f75b55071e
commit 01dc77e5a2
6 changed files with 24 additions and 29 deletions

View File

@ -22,31 +22,31 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
using namespace solidity; using namespace solidity;
namespace solidity::langutil using namespace solidity::langutil;
{ using namespace std;
SourceLocation const parseSourceLocation(std::string const& _input, std::string const& _sourceName, size_t _maxIndex) SourceLocation solidity::langutil::parseSourceLocation(string const& _input, vector<shared_ptr<string const>> const& _sourceNames)
{ {
// Expected input: "start:length:sourceindex" // Expected input: "start:length:sourceindex"
enum SrcElem: size_t { Start, Length, Index }; enum SrcElem: size_t { Start, Length, Index };
std::vector<std::string> pos; vector<string> pos;
boost::algorithm::split(pos, _input, boost::is_any_of(":")); boost::algorithm::split(pos, _input, boost::is_any_of(":"));
// TODO What to do with sourceIndex?
solAssert(pos.size() == 3, "SourceLocation string must have 3 colon separated numeric fields."); solAssert(pos.size() == 3, "SourceLocation string must have 3 colon separated numeric fields.");
auto const sourceIndex = stoi(pos[Index]); auto const sourceIndex = stoi(pos[Index]);
astAssert( astAssert(
sourceIndex == -1 || _maxIndex >= static_cast<size_t>(sourceIndex), sourceIndex == -1 || (0 <= sourceIndex && static_cast<size_t>(sourceIndex) < _sourceNames.size()),
"'src'-field ill-formatted or src-index too high" "'src'-field ill-formatted or src-index too high"
); );
int start = stoi(pos[Start]); int start = stoi(pos[Start]);
int end = start + stoi(pos[Length]); int end = start + stoi(pos[Length]);
return SourceLocation{start, end, std::make_shared<std::string>(_sourceName)}; SourceLocation result{start, end, {}};
} if (sourceIndex != -1)
result.sourceName = _sourceNames.at(static_cast<size_t>(sourceIndex));
return result;
} }

View File

@ -106,10 +106,9 @@ struct SourceLocation
std::shared_ptr<std::string const> sourceName; std::shared_ptr<std::string const> sourceName;
}; };
SourceLocation const parseSourceLocation( SourceLocation parseSourceLocation(
std::string const& _input, std::string const& _input,
std::string const& _sourceName, std::vector<std::shared_ptr<std::string const>> const& _sourceNames
size_t _maxIndex = std::numeric_limits<size_t>::max()
); );
/// Stream output for Location (used e.g. in boost exceptions). /// Stream output for Location (used e.g. in boost exceptions).

View File

@ -57,14 +57,12 @@ ASTPointer<T> ASTJsonImporter::nullOrCast(Json::Value const& _json)
map<string, ASTPointer<SourceUnit>> ASTJsonImporter::jsonToSourceUnit(map<string, Json::Value> const& _sourceList) map<string, ASTPointer<SourceUnit>> ASTJsonImporter::jsonToSourceUnit(map<string, Json::Value> const& _sourceList)
{ {
m_sourceList = _sourceList;
for (auto const& src: _sourceList) for (auto const& src: _sourceList)
m_sourceLocations.emplace_back(make_shared<string const>(src.first)); m_sourceNames.emplace_back(make_shared<string const>(src.first));
for (auto const& srcPair: m_sourceList) for (auto const& srcPair: _sourceList)
{ {
astAssert(!srcPair.second.isNull(), ""); astAssert(!srcPair.second.isNull(), "");
astAssert(member(srcPair.second,"nodeType") == "SourceUnit", "The 'nodeType' of the highest node must be 'SourceUnit'."); astAssert(member(srcPair.second,"nodeType") == "SourceUnit", "The 'nodeType' of the highest node must be 'SourceUnit'.");
m_currentSourceName = srcPair.first;
m_sourceUnits[srcPair.first] = createSourceUnit(srcPair.second, srcPair.first); m_sourceUnits[srcPair.first] = createSourceUnit(srcPair.second, srcPair.first);
} }
return m_sourceUnits; return m_sourceUnits;
@ -94,14 +92,14 @@ SourceLocation const ASTJsonImporter::createSourceLocation(Json::Value const& _n
{ {
astAssert(member(_node, "src").isString(), "'src' must be a string"); astAssert(member(_node, "src").isString(), "'src' must be a string");
return solidity::langutil::parseSourceLocation(_node["src"].asString(), m_currentSourceName, m_sourceLocations.size()); return solidity::langutil::parseSourceLocation(_node["src"].asString(), m_sourceNames);
} }
SourceLocation ASTJsonImporter::createNameSourceLocation(Json::Value const& _node) SourceLocation ASTJsonImporter::createNameSourceLocation(Json::Value const& _node)
{ {
astAssert(member(_node, "nameLocation").isString(), "'nameLocation' must be a string"); astAssert(member(_node, "nameLocation").isString(), "'nameLocation' must be a string");
return solidity::langutil::parseSourceLocation(_node["nameLocation"].asString(), m_currentSourceName, m_sourceLocations.size()); return solidity::langutil::parseSourceLocation(_node["nameLocation"].asString(), m_sourceNames);
} }
template<class T> template<class T>
@ -616,7 +614,7 @@ ASTPointer<InlineAssembly> ASTJsonImporter::createInlineAssembly(Json::Value con
astAssert(m_evmVersion == evmVersion, "Imported tree evm version differs from configured evm version!"); astAssert(m_evmVersion == evmVersion, "Imported tree evm version differs from configured evm version!");
yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(evmVersion.value()); yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(evmVersion.value());
shared_ptr<yul::Block> operations = make_shared<yul::Block>(yul::AsmJsonImporter(m_currentSourceName).createBlock(member(_node, "AST"))); shared_ptr<yul::Block> operations = make_shared<yul::Block>(yul::AsmJsonImporter(m_sourceNames).createBlock(member(_node, "AST")));
return createASTNode<InlineAssembly>( return createASTNode<InlineAssembly>(
_node, _node,
nullOrASTString(_node, "documentation"), nullOrASTString(_node, "documentation"),

View File

@ -152,13 +152,10 @@ private:
///@} ///@}
// =========== member variables =============== // =========== member variables ===============
/// Stores filepath as sourcenames to AST in JSON format /// list of source names, order by source index
std::map<std::string, Json::Value> m_sourceList; std::vector<std::shared_ptr<std::string const>> m_sourceNames;
/// list of filepaths (used as sourcenames)
std::vector<std::shared_ptr<std::string const>> m_sourceLocations;
/// filepath to AST /// filepath to AST
std::map<std::string, ASTPointer<SourceUnit>> m_sourceUnits; std::map<std::string, ASTPointer<SourceUnit>> m_sourceUnits;
std::string m_currentSourceName;
/// IDs already used by the nodes /// IDs already used by the nodes
std::set<int64_t> m_usedIDs; std::set<int64_t> m_usedIDs;
/// Configured EVM version /// Configured EVM version

View File

@ -45,7 +45,7 @@ SourceLocation const AsmJsonImporter::createSourceLocation(Json::Value const& _n
{ {
yulAssert(member(_node, "src").isString(), "'src' must be a string"); yulAssert(member(_node, "src").isString(), "'src' must be a string");
return solidity::langutil::parseSourceLocation(_node["src"].asString(), m_sourceName); return solidity::langutil::parseSourceLocation(_node["src"].asString(), m_sourceNames);
} }
template <class T> template <class T>

View File

@ -38,7 +38,9 @@ namespace solidity::yul
class AsmJsonImporter class AsmJsonImporter
{ {
public: public:
explicit AsmJsonImporter(std::string _sourceName) : m_sourceName(std::move(_sourceName)) {} explicit AsmJsonImporter(std::vector<std::shared_ptr<std::string const>> const& _sourceNames):
m_sourceNames(_sourceNames)
{}
yul::Block createBlock(Json::Value const& _node); yul::Block createBlock(Json::Value const& _node);
private: private:
@ -70,8 +72,7 @@ private:
yul::Break createBreak(Json::Value const& _node); yul::Break createBreak(Json::Value const& _node);
yul::Continue createContinue(Json::Value const& _node); yul::Continue createContinue(Json::Value const& _node);
std::string m_sourceName; std::vector<std::shared_ptr<std::string const>> const& m_sourceNames;
}; };
} }