mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	AsmParser: Accept optional code snippets after the @src tags
This commit is contained in:
		
							parent
							
								
									37f681c430
								
							
						
					
					
						commit
						d78522b08b
					
				| @ -135,7 +135,8 @@ void Parser::fetchSourceLocationFromComment() | ||||
| 		regex_constants::ECMAScript | regex_constants::optimize | ||||
| 	); | ||||
| 	static regex const srcTagArgsRegex = regex( | ||||
| 		R"~~(^(-1|\d+):(-1|\d+):(-1|\d+)(?:\s+|$))~~", // index and location, e.g.: 1:234:-1
 | ||||
| 		R"~~(^(-1|\d+):(-1|\d+):(-1|\d+)(?:\s+|$))~~"  // index and location, e.g.: 1:234:-1
 | ||||
| 		R"~~(("(?:[^"\\]|\\.)*"?)?)~~",                // optional code snippet, e.g.: "string memory s = \"abc\";..." | ||||
| 		regex_constants::ECMAScript | regex_constants::optimize | ||||
| 	); | ||||
| 
 | ||||
| @ -164,9 +165,22 @@ void Parser::fetchSourceLocationFromComment() | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 			solAssert(srcTagArgsMatch.size() == 4, ""); | ||||
| 			solAssert(srcTagArgsMatch.size() == 5, ""); | ||||
| 			position += srcTagArgsMatch.position() + srcTagArgsMatch.length(); | ||||
| 
 | ||||
| 			if (srcTagArgsMatch[4].matched && ( | ||||
| 				!boost::algorithm::ends_with(srcTagArgsMatch[4].str(), "\"") || | ||||
| 				boost::algorithm::ends_with(srcTagArgsMatch[4].str(), "\\\"") | ||||
| 			)) | ||||
| 			{ | ||||
| 				m_errorReporter.syntaxError( | ||||
| 					1544_error, | ||||
| 					commentLocation, | ||||
| 					"Invalid code snippet in source location mapping. Quote is not terminated." | ||||
| 				); | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 			optional<int> const sourceIndex = toInt(srcTagArgsMatch[1].str()); | ||||
| 			optional<int> const start = toInt(srcTagArgsMatch[2].str()); | ||||
| 			optional<int> const end = toInt(srcTagArgsMatch[3].str()); | ||||
|  | ||||
| @ -192,6 +192,7 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): | ||||
|     # white list of ids which are not covered by tests | ||||
|     white_ids = { | ||||
|         "9804", # Tested in test/libyul/ObjectParser.cpp. | ||||
|         "1544", | ||||
|         "2674", | ||||
|         "6367", | ||||
|         "8387", | ||||
|  | ||||
| @ -624,6 +624,20 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_no_whitespace) | ||||
| 	CHECK_LOCATION(result->debugData->location, "", -1, -1); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_separated_with_single_space) | ||||
| { | ||||
| 	ErrorList errorList; | ||||
| 	ErrorReporter reporter(errorList); | ||||
| 	auto const sourceText = R"( | ||||
| 		/// @src 0:111:222 @src 1:333:444
 | ||||
| 		{} | ||||
| 	)"; | ||||
| 	EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); | ||||
| 	shared_ptr<Block> result = parse(sourceText, dialect, reporter); | ||||
| 	BOOST_REQUIRE(!!result && errorList.size() == 0); | ||||
| 	CHECK_LOCATION(result->debugData->location, "source1", 333, 444); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(customSourceLocations_leading_trailing_whitespace) | ||||
| { | ||||
| 	ErrorList errorList; | ||||
| @ -656,6 +670,164 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_reference_original_sloc) | ||||
| 	CHECK_LOCATION(varDecl.debugData->location, "", 10, 20); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets) | ||||
| { | ||||
| 	ErrorList errorList; | ||||
| 	ErrorReporter reporter(errorList); | ||||
| 	auto const sourceText = R"~~~( | ||||
| 		{ | ||||
| 			/// @src 0:149:156  "new C(\"123\")"
 | ||||
| 			let x := 123 | ||||
| 
 | ||||
| 			let y := /** @src 1:96:165  "contract D {..." */ 128 | ||||
| 		} | ||||
| 	)~~~"; | ||||
| 	EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); | ||||
| 	shared_ptr<Block> result = parse(sourceText, dialect, reporter); | ||||
| 	BOOST_REQUIRE(!!result && errorList.size() == 0); | ||||
| 	BOOST_REQUIRE_EQUAL(result->statements.size(), 2); | ||||
| 
 | ||||
| 	BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0))); | ||||
| 	VariableDeclaration const& varX = get<VariableDeclaration>(result->statements.at(0)); | ||||
| 	CHECK_LOCATION(varX.debugData->location, "source0", 149, 156); | ||||
| 
 | ||||
| 	BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(1))); | ||||
| 	VariableDeclaration const& varY = get<VariableDeclaration>(result->statements.at(1)); | ||||
| 	BOOST_REQUIRE(!!varY.value); | ||||
| 	BOOST_REQUIRE(holds_alternative<Literal>(*varY.value)); | ||||
| 	Literal const& literal128 = get<Literal>(*varY.value); | ||||
| 	CHECK_LOCATION(literal128.debugData->location, "source1", 96, 165); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_empty_snippet) | ||||
| { | ||||
| 	ErrorList errorList; | ||||
| 	ErrorReporter reporter(errorList); | ||||
| 	auto const sourceText = R"( | ||||
| 		/// @src 0:111:222 ""
 | ||||
| 		{} | ||||
| 	)"; | ||||
| 	EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); | ||||
| 	shared_ptr<Block> result = parse(sourceText, dialect, reporter); | ||||
| 	BOOST_REQUIRE(!!result && errorList.size() == 0); | ||||
| 	CHECK_LOCATION(result->debugData->location, "source0", 111, 222); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_before_snippet) | ||||
| { | ||||
| 	ErrorList errorList; | ||||
| 	ErrorReporter reporter(errorList); | ||||
| 	auto const sourceText = R"( | ||||
| 		/// @src 0:111:222"abc" def
 | ||||
| 		{} | ||||
| 	)"; | ||||
| 	EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); | ||||
| 	shared_ptr<Block> result = parse(sourceText, dialect, reporter); | ||||
| 	BOOST_REQUIRE(!!result); | ||||
| 	BOOST_REQUIRE(errorList.size() == 1); | ||||
| 	BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); | ||||
| 	BOOST_TEST(errorList[0]->errorId() == 8387_error); | ||||
| 	CHECK_LOCATION(result->debugData->location, "", -1, -1); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_after_snippet) | ||||
| { | ||||
| 	ErrorList errorList; | ||||
| 	ErrorReporter reporter(errorList); | ||||
| 	auto const sourceText = R"( | ||||
| 		/// @src 0:111:222 "abc"def
 | ||||
| 		{} | ||||
| 	)"; | ||||
| 	EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); | ||||
| 	shared_ptr<Block> result = parse(sourceText, dialect, reporter); | ||||
| 	BOOST_REQUIRE(!!result && errorList.size() == 0); | ||||
| 	CHECK_LOCATION(result->debugData->location, "source0", 111, 222); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_no_whitespace) | ||||
| { | ||||
| 	ErrorList errorList; | ||||
| 	ErrorReporter reporter(errorList); | ||||
| 	auto const sourceText = R"( | ||||
| 		/// @src 0:111:222 "abc"@src 1:333:444 "abc"
 | ||||
| 		{} | ||||
| 	)"; | ||||
| 	EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); | ||||
| 	shared_ptr<Block> result = parse(sourceText, dialect, reporter); | ||||
| 	BOOST_REQUIRE(!!result && errorList.size() == 0); | ||||
| 	CHECK_LOCATION(result->debugData->location, "source1", 333, 444); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_unterminated_quote) | ||||
| { | ||||
| 	ErrorList errorList; | ||||
| 	ErrorReporter reporter(errorList); | ||||
| 	auto const sourceText = R"( | ||||
| 		/// @src 0:111:222 " abc @src 1:333:444
 | ||||
| 		{} | ||||
| 	)"; | ||||
| 	EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); | ||||
| 	shared_ptr<Block> result = parse(sourceText, dialect, reporter); | ||||
| 	BOOST_REQUIRE(!!result); | ||||
| 	BOOST_REQUIRE(errorList.size() == 1); | ||||
| 	BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); | ||||
| 	BOOST_TEST(errorList[0]->errorId() == 1544_error); | ||||
| 	CHECK_LOCATION(result->debugData->location, "", -1, -1); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_with_nested_locations) | ||||
| { | ||||
| 	ErrorList errorList; | ||||
| 	ErrorReporter reporter(errorList); | ||||
| 	auto const sourceText = R"~~~( | ||||
| 		{ | ||||
| 			/// @src 0:149:156  "new C(\"123\") /// @src 1:3:4 "
 | ||||
| 			let x := 123 | ||||
| 
 | ||||
| 			let y := /** @src 1:96:165  "function f() internal { \"\/** @src 0:6:7 *\/\"; }" */ 128 | ||||
| 		} | ||||
| 	)~~~"; | ||||
| 	EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); | ||||
| 	shared_ptr<Block> result = parse(sourceText, dialect, reporter); | ||||
| 	BOOST_REQUIRE(!!result && errorList.size() == 0); | ||||
| 	BOOST_REQUIRE_EQUAL(result->statements.size(), 2); | ||||
| 
 | ||||
| 	BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0))); | ||||
| 	VariableDeclaration const& varX = get<VariableDeclaration>(result->statements.at(0)); | ||||
| 	CHECK_LOCATION(varX.debugData->location, "source0", 149, 156); | ||||
| 
 | ||||
| 	BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(1))); | ||||
| 	VariableDeclaration const& varY = get<VariableDeclaration>(result->statements.at(1)); | ||||
| 	BOOST_REQUIRE(!!varY.value); | ||||
| 	BOOST_REQUIRE(holds_alternative<Literal>(*varY.value)); | ||||
| 	Literal const& literal128 = get<Literal>(*varY.value); | ||||
| 	CHECK_LOCATION(literal128.debugData->location, "source1", 96, 165); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(customSourceLocations_multiple_src_tags_on_one_line) | ||||
| { | ||||
| 	ErrorList errorList; | ||||
| 	ErrorReporter reporter(errorList); | ||||
| 	auto const sourceText = | ||||
| 		"{\n" | ||||
| 		"    /// " | ||||
| 			R"~~(@src 1:2:3 ""@src 1:2:4 @src-1:2:5@src 1:2:6 @src 1:2:7     "" @src 1:2:8)~~" | ||||
| 			R"~~( X "@src 0:10:20 "new C(\"123\") /// @src 1:4:5 "" XYZ)~~" | ||||
| 			R"~~( @src0:20:30 "abc"@src0:2:4 @src-0:2:5@)~~" | ||||
| 			R"~~( @some text with random @ signs @@@ @- @** 1:6:7 "src 1:8:9")~~" | ||||
| 		"\n" | ||||
| 		"    let x := 123\n" | ||||
| 		"}\n"; | ||||
| 	EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); | ||||
| 	shared_ptr<Block> result = parse(sourceText, dialect, reporter); | ||||
| 	BOOST_REQUIRE(!!result && errorList.size() == 0); | ||||
| 	BOOST_REQUIRE_EQUAL(result->statements.size(), 1); | ||||
| 
 | ||||
| 	BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0))); | ||||
| 	VariableDeclaration const& varX = get<VariableDeclaration>(result->statements.at(0)); | ||||
| 	CHECK_LOCATION(varX.debugData->location, "source1", 4, 5); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_SUITE_END() | ||||
| 
 | ||||
| } // end namespaces
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user