mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Allow and require use-src to be repeated for each object.
This commit is contained in:
+8
-14
@@ -50,38 +50,32 @@ string indent(std::string const& _input)
|
||||
|
||||
}
|
||||
|
||||
string Data::toString(Dialect const*, optional<SourceNameMap>) const
|
||||
string Data::toString(Dialect const*) const
|
||||
{
|
||||
return "data \"" + name.str() + "\" hex\"" + util::toHex(data) + "\"";
|
||||
}
|
||||
|
||||
string Object::toString(Dialect const* _dialect) const
|
||||
{
|
||||
yulAssert(code, "No code");
|
||||
yulAssert(debugData, "No debug data");
|
||||
|
||||
string useSrcComment;
|
||||
|
||||
if (debugData && debugData->sourceNames)
|
||||
if (debugData->sourceNames)
|
||||
useSrcComment =
|
||||
"/// @use-src " +
|
||||
joinHumanReadable(ranges::views::transform(*debugData->sourceNames, [](auto&& _pair) {
|
||||
return to_string(_pair.first) + ":" + util::escapeAndQuoteString(*_pair.second);
|
||||
})) +
|
||||
"\n";
|
||||
return useSrcComment + toString(_dialect, debugData ? debugData->sourceNames : optional<SourceNameMap>{});
|
||||
}
|
||||
|
||||
string Object::toString(Dialect const* _dialect, std::optional<SourceNameMap> _sourceNames) const
|
||||
{
|
||||
yulAssert(code, "No code");
|
||||
string inner = "code " + AsmPrinter{_dialect, _sourceNames}(*code);
|
||||
string inner = "code " + AsmPrinter{_dialect, debugData->sourceNames}(*code);
|
||||
|
||||
for (auto const& obj: subObjects)
|
||||
{
|
||||
if (auto const* o = dynamic_cast<Object const*>(obj.get()))
|
||||
yulAssert(!o->debugData || !o->debugData->sourceNames, "");
|
||||
inner += "\n" + obj->toString(_dialect, _sourceNames);
|
||||
}
|
||||
inner += "\n" + obj->toString(_dialect);
|
||||
|
||||
return "object \"" + name.str() + "\" {\n" + indent(inner) + "\n}";
|
||||
return useSrcComment + "object \"" + name.str() + "\" {\n" + indent(inner) + "\n}";
|
||||
}
|
||||
|
||||
set<YulString> Object::qualifiedDataNames() const
|
||||
|
||||
+2
-8
@@ -49,11 +49,8 @@ struct ObjectNode
|
||||
/// Name of the object.
|
||||
/// Can be empty since .yul files can also just contain code, without explicitly placing it in an object.
|
||||
YulString name;
|
||||
protected:
|
||||
virtual std::string toString(Dialect const* _dialect, std::optional<SourceNameMap> _sourceNames) const = 0;
|
||||
|
||||
/// Object should have access to toString
|
||||
friend struct Object;
|
||||
virtual std::string toString(Dialect const* _dialect) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -65,8 +62,7 @@ struct Data: public ObjectNode
|
||||
|
||||
bytes data;
|
||||
|
||||
protected:
|
||||
std::string toString(Dialect const* _dialect, std::optional<SourceNameMap> _sourceNames) const override;
|
||||
std::string toString(Dialect const* _dialect) const override;
|
||||
};
|
||||
|
||||
|
||||
@@ -114,8 +110,6 @@ public:
|
||||
|
||||
/// @returns the name of the special metadata data object.
|
||||
static std::string metadataName() { return ".metadata"; }
|
||||
protected:
|
||||
std::string toString(Dialect const* _dialect, std::optional<SourceNameMap> _sourceNames) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+13
-9
@@ -45,14 +45,15 @@ shared_ptr<Object> ObjectParser::parse(shared_ptr<Scanner> const& _scanner, bool
|
||||
{
|
||||
shared_ptr<Object> object;
|
||||
m_scanner = _scanner;
|
||||
m_sourceNameMapping = tryParseSourceNameMapping();
|
||||
|
||||
if (currentToken() == Token::LBrace)
|
||||
{
|
||||
// Special case: Code-only form.
|
||||
object = make_shared<Object>();
|
||||
object->name = "object"_yulstring;
|
||||
object->code = parseBlock();
|
||||
auto sourceNameMapping = tryParseSourceNameMapping();
|
||||
object->debugData = make_shared<ObjectDebugData>(ObjectDebugData{sourceNameMapping});
|
||||
object->code = parseBlock(sourceNameMapping);
|
||||
if (!object->code)
|
||||
return nullptr;
|
||||
}
|
||||
@@ -60,7 +61,6 @@ shared_ptr<Object> ObjectParser::parse(shared_ptr<Scanner> const& _scanner, bool
|
||||
object = parseObject();
|
||||
if (!_reuseScanner)
|
||||
expectToken(Token::EOS);
|
||||
object->debugData = make_shared<ObjectDebugData>(ObjectDebugData{m_sourceNameMapping});
|
||||
return object;
|
||||
}
|
||||
catch (FatalError const&)
|
||||
@@ -75,16 +75,20 @@ shared_ptr<Object> ObjectParser::parseObject(Object* _containingObject)
|
||||
{
|
||||
RecursionGuard guard(*this);
|
||||
|
||||
shared_ptr<Object> ret = make_shared<Object>();
|
||||
|
||||
auto sourceNameMapping = tryParseSourceNameMapping();
|
||||
ret->debugData = make_shared<ObjectDebugData>(ObjectDebugData{sourceNameMapping});
|
||||
|
||||
if (currentToken() != Token::Identifier || currentLiteral() != "object")
|
||||
fatalParserError(4294_error, "Expected keyword \"object\".");
|
||||
advance();
|
||||
|
||||
shared_ptr<Object> ret = make_shared<Object>();
|
||||
ret->name = parseUniqueName(_containingObject);
|
||||
|
||||
expectToken(Token::LBrace);
|
||||
|
||||
ret->code = parseCode();
|
||||
ret->code = parseCode(move(sourceNameMapping));
|
||||
|
||||
while (currentToken() != Token::RBrace)
|
||||
{
|
||||
@@ -103,13 +107,13 @@ shared_ptr<Object> ObjectParser::parseObject(Object* _containingObject)
|
||||
return ret;
|
||||
}
|
||||
|
||||
shared_ptr<Block> ObjectParser::parseCode()
|
||||
shared_ptr<Block> ObjectParser::parseCode(optional<SourceNameMap> _sourceNames)
|
||||
{
|
||||
if (currentToken() != Token::Identifier || currentLiteral() != "code")
|
||||
fatalParserError(4846_error, "Expected keyword \"code\".");
|
||||
advance();
|
||||
|
||||
return parseBlock();
|
||||
return parseBlock(move(_sourceNames));
|
||||
}
|
||||
|
||||
optional<SourceNameMap> ObjectParser::tryParseSourceNameMapping() const
|
||||
@@ -166,9 +170,9 @@ optional<SourceNameMap> ObjectParser::tryParseSourceNameMapping() const
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
shared_ptr<Block> ObjectParser::parseBlock()
|
||||
shared_ptr<Block> ObjectParser::parseBlock(optional<SourceNameMap> _sourceNames)
|
||||
{
|
||||
Parser parser(m_errorReporter, m_dialect, m_sourceNameMapping);
|
||||
Parser parser(m_errorReporter, m_dialect, move(_sourceNames));
|
||||
shared_ptr<Block> block = parser.parseInline(m_scanner);
|
||||
yulAssert(block || m_errorReporter.hasErrors(), "Invalid block but no error!");
|
||||
return block;
|
||||
|
||||
@@ -55,13 +55,11 @@ public:
|
||||
/// @returns an empty shared pointer on error.
|
||||
std::shared_ptr<Object> parse(std::shared_ptr<langutil::Scanner> const& _scanner, bool _reuseScanner);
|
||||
|
||||
std::optional<SourceNameMap> const& sourceNameMapping() const noexcept { return m_sourceNameMapping; }
|
||||
|
||||
private:
|
||||
std::optional<SourceNameMap> tryParseSourceNameMapping() const;
|
||||
std::shared_ptr<Object> parseObject(Object* _containingObject = nullptr);
|
||||
std::shared_ptr<Block> parseCode();
|
||||
std::shared_ptr<Block> parseBlock();
|
||||
std::shared_ptr<Block> parseCode(std::optional<SourceNameMap> _sourceNames);
|
||||
std::shared_ptr<Block> parseBlock(std::optional<SourceNameMap> _sourceNames);
|
||||
void parseData(Object& _containingObject);
|
||||
|
||||
/// Tries to parse a name that is non-empty and unique inside the containing object.
|
||||
@@ -69,8 +67,6 @@ private:
|
||||
void addNamedSubObject(Object& _container, YulString _name, std::shared_ptr<ObjectNode> _subObject);
|
||||
|
||||
Dialect const& m_dialect;
|
||||
|
||||
std::optional<SourceNameMap> m_sourceNameMapping;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -93,6 +93,7 @@ Object EVMToEwasmTranslator::run(Object const& _object)
|
||||
Object ret;
|
||||
ret.name = _object.name;
|
||||
ret.code = make_shared<Block>(move(ast));
|
||||
ret.debugData = _object.debugData;
|
||||
ret.analysisInfo = make_shared<AsmAnalysisInfo>();
|
||||
|
||||
ErrorList errors;
|
||||
|
||||
Reference in New Issue
Block a user