Remove scanner from compiler stack.

This commit is contained in:
chriseth
2021-08-03 15:43:17 +02:00
committed by Christian Parpart
parent af18b8afc2
commit ffc5cfd9a5
23 changed files with 275 additions and 241 deletions
+2 -1
View File
@@ -958,7 +958,8 @@ Json::Value ASTJsonImporter::member(Json::Value const& _node, string const& _nam
Token ASTJsonImporter::scanSingleToken(Json::Value const& _node)
{
langutil::Scanner scanner{langutil::CharStream(_node.asString(), "")};
langutil::CharStream charStream(_node.asString(), "");
langutil::Scanner scanner{charStream};
astAssert(scanner.peekNextToken() == Token::EOS, "Token string is too long.");
return scanner.currentToken();
}
+5 -5
View File
@@ -434,14 +434,14 @@ void CompilerContext::appendInlineAssembly(
ErrorList errors;
ErrorReporter errorReporter(errors);
auto scanner = make_shared<langutil::Scanner>(langutil::CharStream(_assembly, _sourceName));
langutil::CharStream charStream(_assembly, _sourceName);
yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion);
optional<langutil::SourceLocation> locationOverride;
if (!_system)
locationOverride = m_asm->currentSourceLocation();
shared_ptr<yul::Block> parserResult =
yul::Parser(errorReporter, dialect, std::move(locationOverride))
.parse(scanner, false);
.parse(make_shared<langutil::Scanner>(charStream), false);
#ifdef SOL_OUTPUT_ASM
cout << yul::AsmPrinter(&dialect)(*parserResult) << endl;
#endif
@@ -457,7 +457,7 @@ void CompilerContext::appendInlineAssembly(
for (auto const& error: errorReporter.errors())
// TODO if we have "locationOverride", it will be the wrong char stream,
// but we do not have access to the solidity scanner.
message += SourceReferenceFormatter::formatErrorInformation(*error, *scanner->charStream());
message += SourceReferenceFormatter::formatErrorInformation(*error, charStream);
message += "-------------------------------------------\n";
solAssert(false, message);
@@ -491,8 +491,8 @@ void CompilerContext::appendInlineAssembly(
solAssert(m_generatedYulUtilityCode.empty(), "");
m_generatedYulUtilityCode = yul::AsmPrinter(dialect)(*obj.code);
string code = yul::AsmPrinter{dialect}(*obj.code);
scanner = make_shared<langutil::Scanner>(langutil::CharStream(m_generatedYulUtilityCode, _sourceName));
obj.code = yul::Parser(errorReporter, dialect).parse(scanner, false);
langutil::CharStream charStream(m_generatedYulUtilityCode, _sourceName);
obj.code = yul::Parser(errorReporter, dialect).parse(make_shared<Scanner>(charStream), false);
*obj.analysisInfo = yul::AsmAnalyzer::analyzeStrictAssertCorrect(dialect, obj);
}
+17 -17
View File
@@ -313,7 +313,7 @@ void CompilerStack::setSources(StringMap _sources)
if (m_stackState != Empty)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set sources before parsing."));
for (auto source: _sources)
m_sources[source.first].scanner = make_shared<Scanner>(CharStream(/*content*/std::move(source.second), /*name*/source.first));
m_sources[source.first].charStream = make_unique<CharStream>(/*content*/std::move(source.second), /*name*/source.first);
m_stackState = SourcesSet;
}
@@ -336,8 +336,7 @@ bool CompilerStack::parse()
{
string const& path = sourcesToParse[i];
Source& source = m_sources[path];
source.scanner->reset();
source.ast = parser.parse(source.scanner);
source.ast = parser.parse(*source.charStream);
if (!source.ast)
solAssert(!Error::containsOnlyWarnings(m_errorReporter.errors()), "Parser returned null but did not report error.");
else
@@ -348,7 +347,7 @@ bool CompilerStack::parse()
{
string const& newPath = newSource.first;
string const& newContents = newSource.second;
m_sources[newPath].scanner = make_shared<Scanner>(CharStream(newContents, newPath));
m_sources[newPath].charStream = make_shared<CharStream>(newContents, newPath);
sourcesToParse.push_back(newPath);
}
}
@@ -377,10 +376,11 @@ void CompilerStack::importASTs(map<string, Json::Value> const& _sources)
string const& path = src.first;
Source source;
source.ast = src.second;
string srcString = util::jsonCompactPrint(m_sourceJsons[src.first]);
ASTPointer<Scanner> scanner = make_shared<Scanner>(langutil::CharStream(srcString, src.first));
source.scanner = scanner;
m_sources[path] = source;
source.charStream = make_shared<CharStream>(
util::jsonCompactPrint(m_sourceJsons[src.first]),
src.first
);
m_sources[path] = move(source);
}
m_stackState = ParsedAndImported;
m_importedSources = true;
@@ -754,7 +754,8 @@ Json::Value CompilerStack::generatedSources(string const& _contractName, bool _r
unsigned sourceIndex = sourceIndices()[sourceName];
ErrorList errors;
ErrorReporter errorReporter(errors);
auto scanner = make_shared<langutil::Scanner>(langutil::CharStream(source, sourceName));
CharStream charStream(source, sourceName);
shared_ptr<Scanner> scanner = make_shared<Scanner>(charStream);
yul::EVMDialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(m_evmVersion);
shared_ptr<yul::Block> parserResult = yul::Parser{errorReporter, dialect}.parse(scanner, false);
solAssert(parserResult, "");
@@ -1031,10 +1032,9 @@ CharStream const& CompilerStack::charStream(string const& _sourceName) const
if (m_stackState < SourcesSet)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("No sources set."));
solAssert(source(_sourceName).scanner, "");
solAssert(source(_sourceName).scanner->charStream(), "");
solAssert(source(_sourceName).charStream, "");
return *source(_sourceName).scanner->charStream();
return *source(_sourceName).charStream;
}
SourceUnit const& CompilerStack::ast(string const& _sourceName) const
@@ -1079,21 +1079,21 @@ size_t CompilerStack::functionEntryPoint(
h256 const& CompilerStack::Source::keccak256() const
{
if (keccak256HashCached == h256{})
keccak256HashCached = util::keccak256(scanner->source());
keccak256HashCached = util::keccak256(charStream->source());
return keccak256HashCached;
}
h256 const& CompilerStack::Source::swarmHash() const
{
if (swarmHashCached == h256{})
swarmHashCached = util::bzzr1Hash(scanner->source());
swarmHashCached = util::bzzr1Hash(charStream->source());
return swarmHashCached;
}
string const& CompilerStack::Source::ipfsUrl() const
{
if (ipfsUrlCached.empty())
ipfsUrlCached = "dweb:/ipfs/" + util::ipfsHashBase58(scanner->source());
ipfsUrlCached = "dweb:/ipfs/" + util::ipfsHashBase58(charStream->source());
return ipfsUrlCached;
}
@@ -1454,12 +1454,12 @@ string CompilerStack::createMetadata(Contract const& _contract) const
if (!referencedSources.count(s.first))
continue;
solAssert(s.second.scanner, "Scanner not available");
solAssert(s.second.charStream, "Character stream not available");
meta["sources"][s.first]["keccak256"] = "0x" + toHex(s.second.keccak256().asBytes());
if (optional<string> licenseString = s.second.ast->licenseString())
meta["sources"][s.first]["license"] = *licenseString;
if (m_metadataLiteralSources)
meta["sources"][s.first]["content"] = s.second.scanner->source();
meta["sources"][s.first]["content"] = s.second.charStream->source();
else
{
meta["sources"][s.first]["urls"] = Json::arrayValue;
+1 -2
View File
@@ -57,7 +57,6 @@
namespace solidity::langutil
{
class Scanner;
class CharStream;
}
@@ -344,7 +343,7 @@ private:
/// The state per source unit. Filled gradually during parsing.
struct Source
{
std::shared_ptr<langutil::Scanner> scanner;
std::shared_ptr<langutil::CharStream> charStream;
std::shared_ptr<SourceUnit> ast;
util::h256 mutable keccak256HashCached;
util::h256 mutable swarmHashCached;
+7 -4
View File
@@ -81,13 +81,14 @@ private:
SourceLocation m_location;
};
ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
ASTPointer<SourceUnit> Parser::parse(CharStream& _charStream)
{
solAssert(!m_insideModifier, "");
try
{
m_recursionDepth = 0;
m_scanner = _scanner;
m_source = &_charStream;
m_scanner = make_shared<Scanner>(_charStream);
ASTNodeFactory nodeFactory(*this);
vector<ASTPointer<ASTNode>> nodes;
@@ -2056,14 +2057,16 @@ bool Parser::variableDeclarationStart()
optional<string> Parser::findLicenseString(std::vector<ASTPointer<ASTNode>> const& _nodes)
{
solAssert(!!m_source, "");
// We circumvent the scanner here, because it skips non-docstring comments.
static regex const licenseRegex("SPDX-License-Identifier:\\s*([a-zA-Z0-9 ()+.-]+)");
// Search inside all parts of the source not covered by parsed nodes.
// This will leave e.g. "global comments".
string const& source = m_scanner->source();
using iter = decltype(source.begin());
using iter = std::string::const_iterator;
vector<pair<iter, iter>> sequencesToSearch;
string const& source = m_source->source();
sequencesToSearch.emplace_back(source.begin(), source.end());
for (ASTPointer<ASTNode> const& node: _nodes)
if (node->location().hasText())
+3 -2
View File
@@ -29,7 +29,7 @@
namespace solidity::langutil
{
class Scanner;
class CharStream;
}
namespace solidity::frontend
@@ -47,7 +47,7 @@ public:
m_evmVersion(_evmVersion)
{}
ASTPointer<SourceUnit> parse(std::shared_ptr<langutil::Scanner> const& _scanner);
ASTPointer<SourceUnit> parse(langutil::CharStream& _charStream);
private:
class ASTNodeFactory;
@@ -211,6 +211,7 @@ private:
/// Creates an empty ParameterList at the current location (used if parameters can be omitted).
ASTPointer<ParameterList> createEmptyParameterList();
langutil::CharStream* m_source = nullptr;
/// Flag that signifies whether '_' is parsed as a PlaceholderStatement or a regular identifier.
bool m_insideModifier = false;
langutil::EVMVersion m_evmVersion;