mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	refactoring parse() into two separate functions
This commit is contained in:
		
							parent
							
								
									3cbdf6d490
								
							
						
					
					
						commit
						99a7aefb75
					
				| @ -128,14 +128,12 @@ bool CompilerStack::parse() | |||||||
| 	vector<string> sourcesToParse; | 	vector<string> sourcesToParse; | ||||||
| 	for (auto const& s: m_sources) | 	for (auto const& s: m_sources) | ||||||
| 		sourcesToParse.push_back(s.first); | 		sourcesToParse.push_back(s.first); | ||||||
| 	map<string, SourceUnit const*> sourceUnitsByName; |  | ||||||
| 	for (size_t i = 0; i < sourcesToParse.size(); ++i) | 	for (size_t i = 0; i < sourcesToParse.size(); ++i) | ||||||
| 	{ | 	{ | ||||||
| 		string const& path = sourcesToParse[i]; | 		string const& path = sourcesToParse[i]; | ||||||
| 		Source& source = m_sources[path]; | 		Source& source = m_sources[path]; | ||||||
| 		source.scanner->reset(); | 		source.scanner->reset(); | ||||||
| 		source.ast = Parser(m_errors).parse(source.scanner); | 		source.ast = Parser(m_errors).parse(source.scanner); | ||||||
| 		sourceUnitsByName[path] = source.ast.get(); |  | ||||||
| 		if (!source.ast) | 		if (!source.ast) | ||||||
| 			solAssert(!Error::containsOnlyWarnings(m_errors), "Parser returned null but did not report error."); | 			solAssert(!Error::containsOnlyWarnings(m_errors), "Parser returned null but did not report error."); | ||||||
| 		else | 		else | ||||||
| @ -150,9 +148,14 @@ bool CompilerStack::parse() | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if (!Error::containsOnlyWarnings(m_errors)) | 	m_parseSuccessful = Error::containsOnlyWarnings(m_errors); | ||||||
| 		// errors while parsing. should stop before type checking
 | 	return m_parseSuccessful; | ||||||
| 		return false; | } | ||||||
|  | 
 | ||||||
|  | bool CompilerStack::analyze() | ||||||
|  | { | ||||||
|  | 	if (m_sources.empty()) | ||||||
|  | 		BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("There are no sources to be analyzed.")); | ||||||
| 
 | 
 | ||||||
| 	resolveImports(); | 	resolveImports(); | ||||||
| 
 | 
 | ||||||
| @ -173,6 +176,9 @@ bool CompilerStack::parse() | |||||||
| 		if (!resolver.registerDeclarations(*source->ast)) | 		if (!resolver.registerDeclarations(*source->ast)) | ||||||
| 			return false; | 			return false; | ||||||
| 
 | 
 | ||||||
|  | 	map<string, SourceUnit const*> sourceUnitsByName; | ||||||
|  | 	for (auto& source : m_sources) | ||||||
|  | 		sourceUnitsByName[source.first] = source.second.ast.get(); | ||||||
| 	for (Source const* source: m_sourceOrder) | 	for (Source const* source: m_sourceOrder) | ||||||
| 		if (!resolver.performImports(*source->ast, sourceUnitsByName)) | 		if (!resolver.performImports(*source->ast, sourceUnitsByName)) | ||||||
| 			return false; | 			return false; | ||||||
| @ -245,6 +251,17 @@ bool CompilerStack::parse(string const& _sourceCode) | |||||||
| 	return parse(); | 	return parse(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool CompilerStack::parseAndAnalyze() | ||||||
|  | { | ||||||
|  | 	return parse() && analyze(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool CompilerStack::parseAndAnalyze(std::string const& _sourceCode) | ||||||
|  | { | ||||||
|  | 	setSource(_sourceCode); | ||||||
|  | 	return parseAndAnalyze(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| vector<string> CompilerStack::contractNames() const | vector<string> CompilerStack::contractNames() const | ||||||
| { | { | ||||||
| 	if (!m_parseSuccessful) | 	if (!m_parseSuccessful) | ||||||
| @ -259,7 +276,7 @@ vector<string> CompilerStack::contractNames() const | |||||||
| bool CompilerStack::compile(bool _optimize, unsigned _runs, map<string, h160> const& _libraries) | bool CompilerStack::compile(bool _optimize, unsigned _runs, map<string, h160> const& _libraries) | ||||||
| { | { | ||||||
| 	if (!m_parseSuccessful) | 	if (!m_parseSuccessful) | ||||||
| 		if (!parse()) | 		if (!parseAndAnalyze()) | ||||||
| 			return false; | 			return false; | ||||||
| 
 | 
 | ||||||
| 	m_optimize = _optimize; | 	m_optimize = _optimize; | ||||||
| @ -277,7 +294,7 @@ bool CompilerStack::compile(bool _optimize, unsigned _runs, map<string, h160> co | |||||||
| 
 | 
 | ||||||
| bool CompilerStack::compile(string const& _sourceCode, bool _optimize, unsigned _runs) | bool CompilerStack::compile(string const& _sourceCode, bool _optimize, unsigned _runs) | ||||||
| { | { | ||||||
| 	return parse(_sourceCode) && compile(_optimize, _runs); | 	return parseAndAnalyze(_sourceCode) && compile(_optimize, _runs); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void CompilerStack::link() | void CompilerStack::link() | ||||||
|  | |||||||
| @ -103,6 +103,16 @@ public: | |||||||
| 	/// Sets the given source code as the only source unit apart from standard sources and parses it.
 | 	/// Sets the given source code as the only source unit apart from standard sources and parses it.
 | ||||||
| 	/// @returns false on error.
 | 	/// @returns false on error.
 | ||||||
| 	bool parse(std::string const& _sourceCode); | 	bool parse(std::string const& _sourceCode); | ||||||
|  | 	/// performs the analyisis steps (imports, scopesetting, syntaxCheck, referenceResolving,
 | ||||||
|  | 	///  typechecking, staticAnalysis) on the set sources
 | ||||||
|  | 	/// @returns false on error.
 | ||||||
|  | 	bool analyze(); | ||||||
|  | 	/// Parses and analyzes all source units that were added
 | ||||||
|  | 	/// @returns false on error.
 | ||||||
|  | 	bool parseAndAnalyze(); | ||||||
|  | 	/// Sets the given source code as the only source unit apart from standard sources and parses and analyzes it.
 | ||||||
|  | 	/// @returns false on error.
 | ||||||
|  | 	bool parseAndAnalyze(std::string const& _sourceCode); | ||||||
| 	/// @returns a list of the contract names in the sources.
 | 	/// @returns a list of the contract names in the sources.
 | ||||||
| 	std::vector<std::string> contractNames() const; | 	std::vector<std::string> contractNames() const; | ||||||
| 	std::string defaultContractName() const; | 	std::string defaultContractName() const; | ||||||
|  | |||||||
| @ -41,7 +41,7 @@ BOOST_AUTO_TEST_CASE(smoke_test) | |||||||
| { | { | ||||||
| 	CompilerStack c; | 	CompilerStack c; | ||||||
| 	c.addSource("a", "contract C {}"); | 	c.addSource("a", "contract C {}"); | ||||||
| 	c.parse(); | 	c.parseAndAnalyze(); | ||||||
| 	map<string, unsigned> sourceIndices; | 	map<string, unsigned> sourceIndices; | ||||||
| 	sourceIndices["a"] = 1; | 	sourceIndices["a"] = 1; | ||||||
| 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | ||||||
| @ -52,7 +52,7 @@ BOOST_AUTO_TEST_CASE(source_location) | |||||||
| { | { | ||||||
| 	CompilerStack c; | 	CompilerStack c; | ||||||
| 	c.addSource("a", "contract C { function f() { var x = 2; x++; } }"); | 	c.addSource("a", "contract C { function f() { var x = 2; x++; } }"); | ||||||
| 	c.parse(); | 	c.parseAndAnalyze(); | ||||||
| 	map<string, unsigned> sourceIndices; | 	map<string, unsigned> sourceIndices; | ||||||
| 	sourceIndices["a"] = 1; | 	sourceIndices["a"] = 1; | ||||||
| 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | ||||||
| @ -66,7 +66,7 @@ BOOST_AUTO_TEST_CASE(inheritance_specifier) | |||||||
| { | { | ||||||
| 	CompilerStack c; | 	CompilerStack c; | ||||||
| 	c.addSource("a", "contract C1 {} contract C2 is C1 {}"); | 	c.addSource("a", "contract C1 {} contract C2 is C1 {}"); | ||||||
| 	c.parse(); | 	c.parseAndAnalyze(); | ||||||
| 	map<string, unsigned> sourceIndices; | 	map<string, unsigned> sourceIndices; | ||||||
| 	sourceIndices["a"] = 1; | 	sourceIndices["a"] = 1; | ||||||
| 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | ||||||
| @ -81,7 +81,7 @@ BOOST_AUTO_TEST_CASE(using_for_directive) | |||||||
| { | { | ||||||
| 	CompilerStack c; | 	CompilerStack c; | ||||||
| 	c.addSource("a", "library L {} contract C { using L for uint; }"); | 	c.addSource("a", "library L {} contract C { using L for uint; }"); | ||||||
| 	c.parse(); | 	c.parseAndAnalyze(); | ||||||
| 	map<string, unsigned> sourceIndices; | 	map<string, unsigned> sourceIndices; | ||||||
| 	sourceIndices["a"] = 1; | 	sourceIndices["a"] = 1; | ||||||
| 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | ||||||
| @ -91,14 +91,14 @@ BOOST_AUTO_TEST_CASE(using_for_directive) | |||||||
| 	BOOST_CHECK_EQUAL(usingFor["children"][0]["name"], "UserDefinedTypeName"); | 	BOOST_CHECK_EQUAL(usingFor["children"][0]["name"], "UserDefinedTypeName"); | ||||||
| 	BOOST_CHECK_EQUAL(usingFor["children"][0]["attributes"]["name"], "L"); | 	BOOST_CHECK_EQUAL(usingFor["children"][0]["attributes"]["name"], "L"); | ||||||
| 	BOOST_CHECK_EQUAL(usingFor["children"][1]["name"], "ElementaryTypeName"); | 	BOOST_CHECK_EQUAL(usingFor["children"][1]["name"], "ElementaryTypeName"); | ||||||
| 	BOOST_CHECK_EQUAL(usingFor["children"][1]["attributes"]["name"], "uint");     | 	BOOST_CHECK_EQUAL(usingFor["children"][1]["attributes"]["name"], "uint"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BOOST_AUTO_TEST_CASE(enum_value) | BOOST_AUTO_TEST_CASE(enum_value) | ||||||
| { | { | ||||||
| 	CompilerStack c; | 	CompilerStack c; | ||||||
| 	c.addSource("a", "contract C { enum E { A, B } }"); | 	c.addSource("a", "contract C { enum E { A, B } }"); | ||||||
| 	c.parse(); | 	c.parseAndAnalyze(); | ||||||
| 	map<string, unsigned> sourceIndices; | 	map<string, unsigned> sourceIndices; | ||||||
| 	sourceIndices["a"] = 1; | 	sourceIndices["a"] = 1; | ||||||
| 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | ||||||
| @ -115,7 +115,7 @@ BOOST_AUTO_TEST_CASE(modifier_definition) | |||||||
| { | { | ||||||
| 	CompilerStack c; | 	CompilerStack c; | ||||||
| 	c.addSource("a", "contract C { modifier M(uint i) { _; } function F() M(1) {} }"); | 	c.addSource("a", "contract C { modifier M(uint i) { _; } function F() M(1) {} }"); | ||||||
| 	c.parse(); | 	c.parseAndAnalyze(); | ||||||
| 	map<string, unsigned> sourceIndices; | 	map<string, unsigned> sourceIndices; | ||||||
| 	sourceIndices["a"] = 1; | 	sourceIndices["a"] = 1; | ||||||
| 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | ||||||
| @ -129,7 +129,7 @@ BOOST_AUTO_TEST_CASE(modifier_invocation) | |||||||
| { | { | ||||||
| 	CompilerStack c; | 	CompilerStack c; | ||||||
| 	c.addSource("a", "contract C { modifier M(uint i) { _; } function F() M(1) {} }"); | 	c.addSource("a", "contract C { modifier M(uint i) { _; } function F() M(1) {} }"); | ||||||
| 	c.parse(); | 	c.parseAndAnalyze(); | ||||||
| 	map<string, unsigned> sourceIndices; | 	map<string, unsigned> sourceIndices; | ||||||
| 	sourceIndices["a"] = 1; | 	sourceIndices["a"] = 1; | ||||||
| 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | ||||||
| @ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(event_definition) | |||||||
| { | { | ||||||
| 	CompilerStack c; | 	CompilerStack c; | ||||||
| 	c.addSource("a", "contract C { event E(); }"); | 	c.addSource("a", "contract C { event E(); }"); | ||||||
| 	c.parse(); | 	c.parseAndAnalyze(); | ||||||
| 	map<string, unsigned> sourceIndices; | 	map<string, unsigned> sourceIndices; | ||||||
| 	sourceIndices["a"] = 1; | 	sourceIndices["a"] = 1; | ||||||
| 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | ||||||
| @ -159,7 +159,7 @@ BOOST_AUTO_TEST_CASE(array_type_name) | |||||||
| { | { | ||||||
| 	CompilerStack c; | 	CompilerStack c; | ||||||
| 	c.addSource("a", "contract C { uint[] i; }"); | 	c.addSource("a", "contract C { uint[] i; }"); | ||||||
| 	c.parse(); | 	c.parseAndAnalyze(); | ||||||
| 	map<string, unsigned> sourceIndices; | 	map<string, unsigned> sourceIndices; | ||||||
| 	sourceIndices["a"] = 1; | 	sourceIndices["a"] = 1; | ||||||
| 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | ||||||
| @ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE(placeholder_statement) | |||||||
| { | { | ||||||
| 	CompilerStack c; | 	CompilerStack c; | ||||||
| 	c.addSource("a", "contract C { modifier M { _; } }"); | 	c.addSource("a", "contract C { modifier M { _; } }"); | ||||||
| 	c.parse(); | 	c.parseAndAnalyze(); | ||||||
| 	map<string, unsigned> sourceIndices; | 	map<string, unsigned> sourceIndices; | ||||||
| 	sourceIndices["a"] = 1; | 	sourceIndices["a"] = 1; | ||||||
| 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | ||||||
| @ -185,7 +185,7 @@ BOOST_AUTO_TEST_CASE(non_utf8) | |||||||
| { | { | ||||||
| 	CompilerStack c; | 	CompilerStack c; | ||||||
| 	c.addSource("a", "contract C { function f() { var x = hex\"ff\"; } }"); | 	c.addSource("a", "contract C { function f() { var x = hex\"ff\"; } }"); | ||||||
| 	c.parse(); | 	c.parseAndAnalyze(); | ||||||
| 	map<string, unsigned> sourceIndices; | 	map<string, unsigned> sourceIndices; | ||||||
| 	sourceIndices["a"] = 1; | 	sourceIndices["a"] = 1; | ||||||
| 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | ||||||
| @ -204,7 +204,7 @@ BOOST_AUTO_TEST_CASE(function_type) | |||||||
| 		"contract C { function f(function() external payable returns (uint) x) " | 		"contract C { function f(function() external payable returns (uint) x) " | ||||||
| 		"returns (function() external constant returns (uint)) {} }" | 		"returns (function() external constant returns (uint)) {} }" | ||||||
| 	); | 	); | ||||||
| 	c.parse(); | 	c.parseAndAnalyze(); | ||||||
| 	map<string, unsigned> sourceIndices; | 	map<string, unsigned> sourceIndices; | ||||||
| 	sourceIndices["a"] = 1; | 	sourceIndices["a"] = 1; | ||||||
| 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | 	Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); | ||||||
|  | |||||||
| @ -42,7 +42,7 @@ public: | |||||||
| 
 | 
 | ||||||
| 	void checkInterface(std::string const& _code, std::string const& _expectedInterfaceString) | 	void checkInterface(std::string const& _code, std::string const& _expectedInterfaceString) | ||||||
| 	{ | 	{ | ||||||
| 		ETH_TEST_REQUIRE_NO_THROW(m_compilerStack.parse("pragma solidity >=0.0;\n" + _code), "Parsing contract failed"); | 		ETH_TEST_REQUIRE_NO_THROW(m_compilerStack.parseAndAnalyze("pragma solidity >=0.0;\n" + _code), "Parsing contract failed"); | ||||||
| 
 | 
 | ||||||
| 		Json::Value generatedInterface = m_compilerStack.metadata("", DocumentationType::ABIInterface); | 		Json::Value generatedInterface = m_compilerStack.metadata("", DocumentationType::ABIInterface); | ||||||
| 		Json::Value expectedInterface; | 		Json::Value expectedInterface; | ||||||
|  | |||||||
| @ -45,7 +45,7 @@ public: | |||||||
| 		bool _userDocumentation | 		bool _userDocumentation | ||||||
| 	) | 	) | ||||||
| 	{ | 	{ | ||||||
| 		ETH_TEST_REQUIRE_NO_THROW(m_compilerStack.parse("pragma solidity >=0.0;\n" + _code), "Parsing failed"); | 		ETH_TEST_REQUIRE_NO_THROW(m_compilerStack.parseAndAnalyze("pragma solidity >=0.0;\n" + _code), "Parsing failed"); | ||||||
| 
 | 
 | ||||||
| 		Json::Value generatedDocumentation; | 		Json::Value generatedDocumentation; | ||||||
| 		if (_userDocumentation) | 		if (_userDocumentation) | ||||||
| @ -63,7 +63,7 @@ public: | |||||||
| 
 | 
 | ||||||
| 	void expectNatspecError(std::string const& _code) | 	void expectNatspecError(std::string const& _code) | ||||||
| 	{ | 	{ | ||||||
| 		BOOST_CHECK(!m_compilerStack.parse(_code)); | 		BOOST_CHECK(!m_compilerStack.parseAndAnalyze(_code)); | ||||||
| 		BOOST_REQUIRE(Error::containsErrorOfType(m_compilerStack.errors(), Error::Type::DocstringParsingError)); | 		BOOST_REQUIRE(Error::containsErrorOfType(m_compilerStack.errors(), Error::Type::DocstringParsingError)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user