parse_tree_test.cpp 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #include "toolchain/parser/parse_tree.h"
  5. #include <forward_list>
  6. #include "gmock/gmock.h"
  7. #include "gtest/gtest.h"
  8. #include "llvm/ADT/Sequence.h"
  9. #include "llvm/Support/SourceMgr.h"
  10. #include "llvm/Support/YAMLParser.h"
  11. #include "toolchain/diagnostics/diagnostic_emitter.h"
  12. #include "toolchain/lexer/tokenized_buffer.h"
  13. #include "toolchain/lexer/tokenized_buffer_test_helpers.h"
  14. #include "toolchain/parser/parse_node_kind.h"
  15. #include "toolchain/parser/parse_test_helpers.h"
  16. namespace Carbon {
  17. namespace {
  18. using Carbon::Testing::ExpectedNode;
  19. using Carbon::Testing::IsKeyValueScalars;
  20. using Carbon::Testing::MatchParseTreeNodes;
  21. using namespace Carbon::Testing::NodeMatchers;
  22. using ::testing::Eq;
  23. using ::testing::Ne;
  24. using ::testing::NotNull;
  25. using ::testing::StrEq;
  26. struct ParseTreeTest : ::testing::Test {
  27. std::forward_list<SourceBuffer> source_storage;
  28. std::forward_list<TokenizedBuffer> token_storage;
  29. DiagnosticConsumer& consumer = ConsoleDiagnosticConsumer();
  30. auto GetSourceBuffer(llvm::Twine t) -> SourceBuffer& {
  31. source_storage.push_front(SourceBuffer::CreateFromText(t.str()));
  32. return source_storage.front();
  33. }
  34. auto GetTokenizedBuffer(llvm::Twine t) -> TokenizedBuffer& {
  35. token_storage.push_front(
  36. TokenizedBuffer::Lex(GetSourceBuffer(t), consumer));
  37. return token_storage.front();
  38. }
  39. };
  40. TEST_F(ParseTreeTest, Empty) {
  41. TokenizedBuffer tokens = GetTokenizedBuffer("");
  42. ParseTree tree = ParseTree::Parse(tokens, consumer);
  43. EXPECT_FALSE(tree.HasErrors());
  44. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFileEnd()}));
  45. }
  46. TEST_F(ParseTreeTest, EmptyDeclaration) {
  47. TokenizedBuffer tokens = GetTokenizedBuffer(";");
  48. ParseTree tree = ParseTree::Parse(tokens, consumer);
  49. EXPECT_FALSE(tree.HasErrors());
  50. auto it = tree.Postorder().begin();
  51. auto end = tree.Postorder().end();
  52. ASSERT_THAT(it, Ne(end));
  53. ParseTree::Node n = *it++;
  54. ASSERT_THAT(it, Ne(end));
  55. ParseTree::Node eof = *it++;
  56. EXPECT_THAT(it, Eq(end));
  57. // Directly test the main API so that we get easier to understand errors in
  58. // simple cases than what the custom matcher will produce.
  59. EXPECT_FALSE(tree.HasErrorInNode(n));
  60. EXPECT_FALSE(tree.HasErrorInNode(eof));
  61. EXPECT_THAT(tree.GetNodeKind(n), Eq(ParseNodeKind::EmptyDeclaration()));
  62. EXPECT_THAT(tree.GetNodeKind(eof), Eq(ParseNodeKind::FileEnd()));
  63. auto t = tree.GetNodeToken(n);
  64. ASSERT_THAT(tokens.Tokens().begin(), Ne(tokens.Tokens().end()));
  65. EXPECT_THAT(t, Eq(*tokens.Tokens().begin()));
  66. EXPECT_THAT(tokens.GetTokenText(t), Eq(";"));
  67. EXPECT_THAT(tree.Children(n).begin(), Eq(tree.Children(n).end()));
  68. EXPECT_THAT(tree.Children(eof).begin(), Eq(tree.Children(eof).end()));
  69. EXPECT_THAT(tree.Postorder().begin(), Eq(tree.Postorder(n).begin()));
  70. EXPECT_THAT(tree.Postorder(n).end(), Eq(tree.Postorder(eof).begin()));
  71. EXPECT_THAT(tree.Postorder(eof).end(), Eq(tree.Postorder().end()));
  72. }
  73. TEST_F(ParseTreeTest, BasicFunctionDeclaration) {
  74. TokenizedBuffer tokens = GetTokenizedBuffer("fn F();");
  75. ParseTree tree = ParseTree::Parse(tokens, consumer);
  76. EXPECT_FALSE(tree.HasErrors());
  77. EXPECT_THAT(tree, MatchParseTreeNodes(
  78. {MatchFunctionDeclaration("fn", MatchDeclaredName("F"),
  79. MatchParameters(),
  80. MatchDeclarationEnd(";")),
  81. MatchFileEnd()}));
  82. }
  83. TEST_F(ParseTreeTest, NoDeclarationIntroducerOrSemi) {
  84. TokenizedBuffer tokens = GetTokenizedBuffer("foo bar baz");
  85. ParseTree tree = ParseTree::Parse(tokens, consumer);
  86. EXPECT_TRUE(tree.HasErrors());
  87. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFileEnd()}));
  88. }
  89. TEST_F(ParseTreeTest, NoDeclarationIntroducerWithSemi) {
  90. TokenizedBuffer tokens = GetTokenizedBuffer("foo;");
  91. ParseTree tree = ParseTree::Parse(tokens, consumer);
  92. EXPECT_TRUE(tree.HasErrors());
  93. EXPECT_THAT(tree, MatchParseTreeNodes({MatchEmptyDeclaration(";", HasError),
  94. MatchFileEnd()}));
  95. }
  96. TEST_F(ParseTreeTest, JustFunctionIntroducerAndSemi) {
  97. TokenizedBuffer tokens = GetTokenizedBuffer("fn;");
  98. ParseTree tree = ParseTree::Parse(tokens, consumer);
  99. EXPECT_TRUE(tree.HasErrors());
  100. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFunctionDeclaration(
  101. HasError, MatchDeclarationEnd()),
  102. MatchFileEnd()}));
  103. }
  104. TEST_F(ParseTreeTest, RepeatedFunctionIntroducerAndSemi) {
  105. TokenizedBuffer tokens = GetTokenizedBuffer("fn fn;");
  106. ParseTree tree = ParseTree::Parse(tokens, consumer);
  107. EXPECT_TRUE(tree.HasErrors());
  108. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFunctionDeclaration(
  109. HasError, MatchDeclarationEnd()),
  110. MatchFileEnd()}));
  111. }
  112. TEST_F(ParseTreeTest, FunctionDeclarationWithNoSignatureOrSemi) {
  113. TokenizedBuffer tokens = GetTokenizedBuffer("fn foo");
  114. ParseTree tree = ParseTree::Parse(tokens, consumer);
  115. EXPECT_TRUE(tree.HasErrors());
  116. EXPECT_THAT(tree,
  117. MatchParseTreeNodes(
  118. {MatchFunctionDeclaration(HasError, MatchDeclaredName("foo")),
  119. MatchFileEnd()}));
  120. }
  121. TEST_F(ParseTreeTest,
  122. FunctionDeclarationWithIdentifierInsteadOfSignatureAndSemi) {
  123. TokenizedBuffer tokens = GetTokenizedBuffer("fn foo bar;");
  124. ParseTree tree = ParseTree::Parse(tokens, consumer);
  125. EXPECT_TRUE(tree.HasErrors());
  126. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFunctionDeclaration(
  127. HasError, MatchDeclaredName("foo"),
  128. MatchDeclarationEnd()),
  129. MatchFileEnd()}));
  130. }
  131. TEST_F(ParseTreeTest, FunctionDeclarationWithParameterList) {
  132. TokenizedBuffer tokens = GetTokenizedBuffer("fn foo(bar: Int, baz: Int);");
  133. ParseTree tree = ParseTree::Parse(tokens, consumer);
  134. EXPECT_FALSE(tree.HasErrors());
  135. EXPECT_THAT(tree,
  136. MatchParseTreeNodes(
  137. {MatchFunctionDeclaration(
  138. MatchDeclaredName("foo"),
  139. MatchParameterList(
  140. MatchPatternBinding(MatchDeclaredName("bar"), ":",
  141. MatchNameReference("Int")),
  142. MatchParameterListComma(),
  143. MatchPatternBinding(MatchDeclaredName("baz"), ":",
  144. MatchNameReference("Int")),
  145. MatchParameterListEnd()),
  146. MatchDeclarationEnd()),
  147. MatchFileEnd()}));
  148. }
  149. TEST_F(ParseTreeTest, FunctionDefinitionWithParameterList) {
  150. TokenizedBuffer tokens = GetTokenizedBuffer(
  151. "fn foo(bar: Int, baz: Int) {\n"
  152. " foo(baz, bar + baz);\n"
  153. "}");
  154. ParseTree tree = ParseTree::Parse(tokens, consumer);
  155. EXPECT_FALSE(tree.HasErrors());
  156. EXPECT_THAT(
  157. tree,
  158. MatchParseTreeNodes(
  159. {MatchFunctionDeclaration(
  160. MatchDeclaredName("foo"),
  161. MatchParameterList(
  162. MatchPatternBinding(MatchDeclaredName("bar"), ":",
  163. MatchNameReference("Int")),
  164. MatchParameterListComma(),
  165. MatchPatternBinding(MatchDeclaredName("baz"), ":",
  166. MatchNameReference("Int")),
  167. MatchParameterListEnd()),
  168. MatchCodeBlock(
  169. MatchExpressionStatement(MatchCallExpression(
  170. MatchNameReference("foo"), MatchNameReference("baz"),
  171. MatchCallExpressionComma(),
  172. MatchInfixOperator(MatchNameReference("bar"), "+",
  173. MatchNameReference("baz")),
  174. MatchCallExpressionEnd())),
  175. MatchCodeBlockEnd())),
  176. MatchFileEnd()}));
  177. }
  178. TEST_F(ParseTreeTest, FunctionDeclarationWithReturnType) {
  179. TokenizedBuffer tokens = GetTokenizedBuffer("fn foo() -> Int;");
  180. ParseTree tree = ParseTree::Parse(tokens, consumer);
  181. EXPECT_FALSE(tree.HasErrors());
  182. EXPECT_THAT(
  183. tree,
  184. MatchParseTreeNodes(
  185. {MatchFunctionDeclaration(MatchDeclaredName("foo"), MatchParameters(),
  186. MatchReturnType(MatchNameReference("Int")),
  187. MatchDeclarationEnd()),
  188. MatchFileEnd()}));
  189. }
  190. TEST_F(ParseTreeTest, FunctionDefinitionWithReturnType) {
  191. TokenizedBuffer tokens = GetTokenizedBuffer(
  192. "fn foo() -> Int {\n"
  193. " return 42;\n"
  194. "}");
  195. ParseTree tree = ParseTree::Parse(tokens, consumer);
  196. EXPECT_FALSE(tree.HasErrors());
  197. EXPECT_THAT(tree,
  198. MatchParseTreeNodes(
  199. {MatchFunctionDeclaration(
  200. MatchDeclaredName("foo"), MatchParameters(),
  201. MatchReturnType(MatchNameReference("Int")),
  202. MatchCodeBlock(MatchReturnStatement(MatchLiteral("42"),
  203. MatchStatementEnd()),
  204. MatchCodeBlockEnd())),
  205. MatchFileEnd()}));
  206. }
  207. TEST_F(ParseTreeTest, FunctionDeclarationWithSingleIdentifierParameterList) {
  208. TokenizedBuffer tokens = GetTokenizedBuffer("fn foo(bar);");
  209. ParseTree tree = ParseTree::Parse(tokens, consumer);
  210. // Note: this might become valid depending on the parameter syntax, this test
  211. // shouldn't be taken as a sign it should remain invalid.
  212. EXPECT_TRUE(tree.HasErrors());
  213. EXPECT_THAT(tree,
  214. MatchParseTreeNodes(
  215. {MatchFunctionDeclaration(
  216. MatchDeclaredName("foo"),
  217. MatchParameterList(HasError, MatchParameterListEnd()),
  218. MatchDeclarationEnd()),
  219. MatchFileEnd()}));
  220. }
  221. TEST_F(ParseTreeTest, FunctionDeclarationWithoutName) {
  222. TokenizedBuffer tokens = GetTokenizedBuffer("fn ();");
  223. ParseTree tree = ParseTree::Parse(tokens, consumer);
  224. EXPECT_TRUE(tree.HasErrors());
  225. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFunctionDeclaration(
  226. HasError, MatchDeclarationEnd()),
  227. MatchFileEnd()}));
  228. }
  229. TEST_F(ParseTreeTest,
  230. FunctionDeclarationWithoutNameAndManyTokensToSkipInGroupedSymbols) {
  231. TokenizedBuffer tokens = GetTokenizedBuffer(
  232. "fn (a tokens c d e f g h i j k l m n o p q r s t u v w x y z);");
  233. ParseTree tree = ParseTree::Parse(tokens, consumer);
  234. EXPECT_TRUE(tree.HasErrors());
  235. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFunctionDeclaration(
  236. HasError, MatchDeclarationEnd()),
  237. MatchFileEnd()}));
  238. }
  239. TEST_F(ParseTreeTest, FunctionDeclarationSkipToNewlineWithoutSemi) {
  240. TokenizedBuffer tokens = GetTokenizedBuffer(
  241. "fn ()\n"
  242. "fn F();");
  243. ParseTree tree = ParseTree::Parse(tokens, consumer);
  244. EXPECT_TRUE(tree.HasErrors());
  245. EXPECT_THAT(
  246. tree, MatchParseTreeNodes({MatchFunctionDeclaration(HasError),
  247. MatchFunctionDeclaration(
  248. MatchDeclaredName("F"), MatchParameters(),
  249. MatchDeclarationEnd()),
  250. MatchFileEnd()}));
  251. }
  252. TEST_F(ParseTreeTest, FunctionDeclarationSkipIndentedNewlineWithSemi) {
  253. TokenizedBuffer tokens = GetTokenizedBuffer(
  254. "fn (x,\n"
  255. " y,\n"
  256. " z);\n"
  257. "fn F();");
  258. ParseTree tree = ParseTree::Parse(tokens, consumer);
  259. EXPECT_TRUE(tree.HasErrors());
  260. EXPECT_THAT(
  261. tree,
  262. MatchParseTreeNodes(
  263. {MatchFunctionDeclaration(HasError, MatchDeclarationEnd()),
  264. MatchFunctionDeclaration(MatchDeclaredName("F"), MatchParameters(),
  265. MatchDeclarationEnd()),
  266. MatchFileEnd()}));
  267. }
  268. TEST_F(ParseTreeTest, FunctionDeclarationSkipIndentedNewlineWithoutSemi) {
  269. TokenizedBuffer tokens = GetTokenizedBuffer(
  270. "fn (x,\n"
  271. " y,\n"
  272. " z)\n"
  273. "fn F();");
  274. ParseTree tree = ParseTree::Parse(tokens, consumer);
  275. EXPECT_TRUE(tree.HasErrors());
  276. EXPECT_THAT(
  277. tree, MatchParseTreeNodes({MatchFunctionDeclaration(HasError),
  278. MatchFunctionDeclaration(
  279. MatchDeclaredName("F"), MatchParameters(),
  280. MatchDeclarationEnd()),
  281. MatchFileEnd()}));
  282. }
  283. TEST_F(ParseTreeTest, FunctionDeclarationSkipIndentedNewlineUntilOutdent) {
  284. TokenizedBuffer tokens = GetTokenizedBuffer(
  285. " fn (x,\n"
  286. " y,\n"
  287. " z)\n"
  288. "fn F();");
  289. ParseTree tree = ParseTree::Parse(tokens, consumer);
  290. EXPECT_TRUE(tree.HasErrors());
  291. EXPECT_THAT(
  292. tree, MatchParseTreeNodes({MatchFunctionDeclaration(HasError),
  293. MatchFunctionDeclaration(
  294. MatchDeclaredName("F"), MatchParameters(),
  295. MatchDeclarationEnd()),
  296. MatchFileEnd()}));
  297. }
  298. TEST_F(ParseTreeTest, FunctionDeclarationSkipWithoutSemiToCurly) {
  299. // FIXME: We don't have a grammar construct that uses curlies yet so this just
  300. // won't parse at all. Once it does, we should ensure that the close brace
  301. // gets properly parsed for the struct (or whatever other curly-braced syntax
  302. // we have grouping function declarations) despite the invalid function
  303. // declaration missing a semicolon.
  304. TokenizedBuffer tokens = GetTokenizedBuffer(
  305. "struct X { fn () }\n"
  306. "fn F();");
  307. ParseTree tree = ParseTree::Parse(tokens, consumer);
  308. EXPECT_TRUE(tree.HasErrors());
  309. }
  310. TEST_F(ParseTreeTest, BasicFunctionDefinition) {
  311. TokenizedBuffer tokens = GetTokenizedBuffer(
  312. "fn F() {\n"
  313. "}");
  314. ParseTree tree = ParseTree::Parse(tokens, consumer);
  315. EXPECT_FALSE(tree.HasErrors());
  316. EXPECT_THAT(tree, MatchParseTreeNodes(
  317. {MatchFunctionDeclaration(
  318. MatchDeclaredName("F"), MatchParameters(),
  319. MatchCodeBlock("{", MatchCodeBlockEnd("}"))),
  320. MatchFileEnd()}));
  321. }
  322. TEST_F(ParseTreeTest, FunctionDefinitionWithNestedBlocks) {
  323. TokenizedBuffer tokens = GetTokenizedBuffer(
  324. "fn F() {\n"
  325. " {\n"
  326. " {{}}\n"
  327. " }\n"
  328. "}");
  329. ParseTree tree = ParseTree::Parse(tokens, consumer);
  330. EXPECT_FALSE(tree.HasErrors());
  331. EXPECT_THAT(
  332. tree, MatchParseTreeNodes(
  333. {MatchFunctionDeclaration(
  334. MatchDeclaredName("F"), MatchParameters(),
  335. MatchCodeBlock(
  336. MatchCodeBlock(
  337. MatchCodeBlock(MatchCodeBlock(MatchCodeBlockEnd()),
  338. MatchCodeBlockEnd()),
  339. MatchCodeBlockEnd()),
  340. MatchCodeBlockEnd())),
  341. MatchFileEnd()}));
  342. }
  343. TEST_F(ParseTreeTest, FunctionDefinitionWithIdenifierInStatements) {
  344. TokenizedBuffer tokens = GetTokenizedBuffer(
  345. "fn F() {\n"
  346. " bar\n"
  347. "}");
  348. ParseTree tree = ParseTree::Parse(tokens, consumer);
  349. // Note: this might become valid depending on the expression syntax. This test
  350. // shouldn't be taken as a sign it should remain invalid.
  351. EXPECT_TRUE(tree.HasErrors());
  352. EXPECT_THAT(tree, MatchParseTreeNodes(
  353. {MatchFunctionDeclaration(
  354. MatchDeclaredName("F"), MatchParameters(),
  355. MatchCodeBlock(HasError, MatchNameReference("bar"),
  356. MatchCodeBlockEnd())),
  357. MatchFileEnd()}));
  358. }
  359. TEST_F(ParseTreeTest, FunctionDefinitionWithIdenifierInNestedBlock) {
  360. TokenizedBuffer tokens = GetTokenizedBuffer(
  361. "fn F() {\n"
  362. " {bar}\n"
  363. "}");
  364. ParseTree tree = ParseTree::Parse(tokens, consumer);
  365. // Note: this might become valid depending on the expression syntax. This test
  366. // shouldn't be taken as a sign it should remain invalid.
  367. EXPECT_TRUE(tree.HasErrors());
  368. EXPECT_THAT(tree,
  369. MatchParseTreeNodes(
  370. {MatchFunctionDeclaration(
  371. MatchDeclaredName("F"), MatchParameters(),
  372. MatchCodeBlock(
  373. MatchCodeBlock(HasError, MatchNameReference("bar"),
  374. MatchCodeBlockEnd()),
  375. MatchCodeBlockEnd())),
  376. MatchFileEnd()}));
  377. }
  378. TEST_F(ParseTreeTest, FunctionDefinitionWithFunctionCall) {
  379. TokenizedBuffer tokens = GetTokenizedBuffer(
  380. "fn F() {\n"
  381. " a.b.f(c.d, (e)).g();\n"
  382. "}");
  383. ParseTree tree = ParseTree::Parse(tokens, consumer);
  384. EXPECT_FALSE(tree.HasErrors());
  385. ExpectedNode call_to_f = MatchCallExpression(
  386. MatchDesignator(MatchDesignator(MatchNameReference("a"), "b"), "f"),
  387. MatchDesignator(MatchNameReference("c"), "d"), MatchCallExpressionComma(),
  388. MatchParenExpression(MatchNameReference("e"), MatchParenExpressionEnd()),
  389. MatchCallExpressionEnd());
  390. ExpectedNode statement = MatchExpressionStatement(MatchCallExpression(
  391. MatchDesignator(call_to_f, "g"), MatchCallExpressionEnd()));
  392. EXPECT_THAT(tree, MatchParseTreeNodes(
  393. {MatchFunctionWithBody(statement), MatchFileEnd()}));
  394. }
  395. TEST_F(ParseTreeTest, InvalidDesignators) {
  396. TokenizedBuffer tokens = GetTokenizedBuffer(
  397. "fn F() {\n"
  398. " a.;\n"
  399. " a.fn;\n"
  400. " a.42;\n"
  401. "}");
  402. ParseTree tree = ParseTree::Parse(tokens, consumer);
  403. EXPECT_TRUE(tree.HasErrors());
  404. EXPECT_THAT(tree, MatchParseTreeNodes(
  405. {MatchFunctionWithBody(
  406. MatchExpressionStatement(
  407. MatchDesignatorExpression(
  408. MatchNameReference("a"), ".", HasError),
  409. ";"),
  410. MatchExpressionStatement(
  411. MatchDesignatorExpression(
  412. MatchNameReference("a"), ".", HasError),
  413. ";"),
  414. MatchExpressionStatement(
  415. MatchDesignatorExpression(
  416. MatchNameReference("a"), ".", HasError),
  417. HasError, ";")),
  418. MatchFileEnd()}));
  419. }
  420. TEST_F(ParseTreeTest, Operators) {
  421. TokenizedBuffer tokens = GetTokenizedBuffer(
  422. "fn F() {\n"
  423. " n = a * b + c * d = d * d << e & f - not g;\n"
  424. " ++++n;\n"
  425. " n++++;\n"
  426. " a and b and c;\n"
  427. " a and b or c;\n"
  428. " a or b and c;\n"
  429. " not a and not b and not c;\n"
  430. "}");
  431. ParseTree tree = ParseTree::Parse(tokens, consumer);
  432. EXPECT_TRUE(tree.HasErrors());
  433. EXPECT_THAT(
  434. tree,
  435. MatchParseTreeNodes(
  436. {MatchFunctionWithBody(
  437. MatchExpressionStatement(MatchInfixOperator(
  438. MatchNameReference("n"), "=",
  439. MatchInfixOperator(
  440. MatchInfixOperator(
  441. MatchInfixOperator(MatchNameReference("a"), "*",
  442. MatchNameReference("b")),
  443. "+",
  444. MatchInfixOperator(MatchNameReference("c"), "*",
  445. MatchNameReference("d"))),
  446. "=",
  447. MatchInfixOperator(
  448. HasError,
  449. MatchInfixOperator(
  450. HasError,
  451. MatchInfixOperator(
  452. HasError,
  453. MatchInfixOperator(MatchNameReference("d"),
  454. "*",
  455. MatchNameReference("d")),
  456. "<<", MatchNameReference("e")),
  457. "&", MatchNameReference("f")),
  458. "-",
  459. MatchPrefixOperator("not",
  460. MatchNameReference("g")))))),
  461. MatchExpressionStatement(MatchPrefixOperator(
  462. "++", MatchPrefixOperator("++", MatchNameReference("n")))),
  463. MatchExpressionStatement(MatchPostfixOperator(
  464. MatchPostfixOperator(MatchNameReference("n"), "++"), "++")),
  465. MatchExpressionStatement(MatchInfixOperator(
  466. MatchInfixOperator(MatchNameReference("a"), "and",
  467. MatchNameReference("b")),
  468. "and", MatchNameReference("c"))),
  469. MatchExpressionStatement(MatchInfixOperator(
  470. HasError,
  471. MatchInfixOperator(MatchNameReference("a"), "and",
  472. MatchNameReference("b")),
  473. "or", MatchNameReference("c"))),
  474. MatchExpressionStatement(MatchInfixOperator(
  475. HasError,
  476. MatchInfixOperator(MatchNameReference("a"), "or",
  477. MatchNameReference("b")),
  478. "and", MatchNameReference("c"))),
  479. MatchExpressionStatement(MatchInfixOperator(
  480. MatchInfixOperator(
  481. MatchPrefixOperator("not", MatchNameReference("a")),
  482. "and",
  483. MatchPrefixOperator("not", MatchNameReference("b"))),
  484. "and",
  485. MatchPrefixOperator("not", MatchNameReference("c"))))),
  486. MatchFileEnd()}));
  487. }
  488. TEST_F(ParseTreeTest, OperatorFixity) {
  489. TokenizedBuffer tokens = GetTokenizedBuffer(
  490. "fn F(p: Int*, n: Int) {\n"
  491. " var q: Int* = p;\n"
  492. " var t: Type = Int*;\n"
  493. " t = t**;\n"
  494. " n = n * n;\n"
  495. " n = n*n;\n"
  496. " G(Int*, n * n);\n"
  497. "}");
  498. ParseTree tree = ParseTree::Parse(tokens, consumer);
  499. EXPECT_FALSE(tree.HasErrors());
  500. EXPECT_THAT(
  501. tree,
  502. MatchParseTreeNodes(
  503. {MatchFunctionDeclaration(
  504. MatchDeclaredName("F"),
  505. MatchParameters(
  506. MatchPatternBinding(
  507. MatchDeclaredName("p"),
  508. MatchPostfixOperator(MatchNameReference("Int"), "*")),
  509. MatchParameterListComma(),
  510. MatchPatternBinding(MatchDeclaredName("n"),
  511. MatchNameReference("Int"))),
  512. MatchCodeBlock(
  513. MatchVariableDeclaration(
  514. MatchPatternBinding(MatchDeclaredName("q"),
  515. MatchPostfixOperator(
  516. MatchNameReference("Int"), "*")),
  517. MatchVariableInitializer(MatchNameReference("p")),
  518. MatchDeclarationEnd()),
  519. MatchVariableDeclaration(
  520. MatchPatternBinding(MatchDeclaredName("t"),
  521. MatchNameReference("Type")),
  522. MatchVariableInitializer(MatchPostfixOperator(
  523. MatchNameReference("Int"), "*")),
  524. MatchDeclarationEnd()),
  525. MatchExpressionStatement(MatchInfixOperator(
  526. MatchNameReference("t"), "=",
  527. MatchPostfixOperator(
  528. MatchPostfixOperator(MatchNameReference("t"), "*"),
  529. "*"))),
  530. MatchExpressionStatement(MatchInfixOperator(
  531. MatchNameReference("n"), "=",
  532. MatchInfixOperator(MatchNameReference("n"), "*",
  533. MatchNameReference("n")))),
  534. MatchExpressionStatement(MatchInfixOperator(
  535. MatchNameReference("n"), "=",
  536. MatchInfixOperator(MatchNameReference("n"), "*",
  537. MatchNameReference("n")))),
  538. MatchExpressionStatement(MatchCallExpression(
  539. MatchNameReference("G"),
  540. MatchPostfixOperator(MatchNameReference("Int"), "*"),
  541. MatchCallExpressionComma(),
  542. MatchInfixOperator(MatchNameReference("n"), "*",
  543. MatchNameReference("n")),
  544. MatchCallExpressionEnd())),
  545. MatchCodeBlockEnd())),
  546. MatchFileEnd()}));
  547. }
  548. TEST_F(ParseTreeTest, OperatorWhitespaceErrors) {
  549. // Test dispositions: Recovered means we issued an error but recovered a
  550. // proper parse tree; Failed means we didn't fully recover from the error.
  551. enum Kind { Valid, Recovered, Failed };
  552. struct Testcase {
  553. const char* input;
  554. Kind kind;
  555. } testcases[] = {
  556. {"var v: Type = Int*;", Valid},
  557. {"var v: Type = Int *;", Recovered},
  558. {"var v: Type = Int* ;", Valid},
  559. {"var v: Type = Int * ;", Recovered},
  560. {"var n: Int = n * n;", Valid},
  561. {"var n: Int = n*n;", Valid},
  562. {"var n: Int = (n)*3;", Valid},
  563. {"var n: Int = 3*(n);", Valid},
  564. {"var n: Int = n *n;", Recovered},
  565. // FIXME: We could figure out that this first Failed example is infix
  566. // with one-token lookahead.
  567. {"var n: Int = n* n;", Failed},
  568. {"var n: Int = n* -n;", Failed},
  569. {"var n: Int = n* *p;", Failed},
  570. // FIXME: We try to form (n*)*p and reject due to missing parentheses
  571. // before we notice the missing whitespace around the second `*`.
  572. // It'd be better to (somehow) form n*(*p) and reject due to the missing
  573. // whitespace around the first `*`.
  574. {"var n: Int = n**p;", Failed},
  575. {"var n: Int = -n;", Valid},
  576. {"var n: Int = - n;", Recovered},
  577. {"var n: Int =-n;", Valid},
  578. {"var n: Int =- n;", Recovered},
  579. {"var n: Int = F(Int *);", Recovered},
  580. {"var n: Int = F(Int *, 0);", Recovered},
  581. };
  582. for (auto [input, kind] : testcases) {
  583. TokenizedBuffer tokens = GetTokenizedBuffer(input);
  584. ErrorTrackingDiagnosticConsumer error_tracker(consumer);
  585. ParseTree tree = ParseTree::Parse(tokens, error_tracker);
  586. EXPECT_THAT(tree.HasErrors(), Eq(kind == Failed)) << input;
  587. EXPECT_THAT(error_tracker.SeenError(), Eq(kind != Valid)) << input;
  588. }
  589. }
  590. TEST_F(ParseTreeTest, VariableDeclarations) {
  591. TokenizedBuffer tokens = GetTokenizedBuffer(
  592. "var v: Int = 0;\n"
  593. "var w: Int;\n"
  594. "fn F() {\n"
  595. " var s: String = \"hello\";\n"
  596. "}");
  597. ParseTree tree = ParseTree::Parse(tokens, consumer);
  598. EXPECT_FALSE(tree.HasErrors());
  599. EXPECT_THAT(tree,
  600. MatchParseTreeNodes(
  601. {MatchVariableDeclaration(
  602. MatchPatternBinding(MatchDeclaredName("v"), ":",
  603. MatchNameReference("Int")),
  604. MatchVariableInitializer(MatchLiteral("0")),
  605. MatchDeclarationEnd()),
  606. MatchVariableDeclaration(
  607. MatchPatternBinding(MatchDeclaredName("w"), ":",
  608. MatchNameReference("Int")),
  609. MatchDeclarationEnd()),
  610. MatchFunctionWithBody(MatchVariableDeclaration(
  611. MatchPatternBinding(MatchDeclaredName("s"), ":",
  612. MatchNameReference("String")),
  613. MatchVariableInitializer(MatchLiteral("\"hello\"")),
  614. MatchDeclarationEnd())),
  615. MatchFileEnd()}));
  616. }
  617. TEST_F(ParseTreeTest, IfNoElse) {
  618. TokenizedBuffer tokens = GetTokenizedBuffer(
  619. "fn F() {\n"
  620. " if (a)\n"
  621. " if (b)\n"
  622. " if (c)\n"
  623. " d;\n"
  624. "}");
  625. ParseTree tree = ParseTree::Parse(tokens, consumer);
  626. EXPECT_FALSE(tree.HasErrors());
  627. EXPECT_THAT(
  628. tree,
  629. MatchParseTreeNodes(
  630. {MatchFunctionWithBody(MatchIfStatement(
  631. MatchCondition(MatchNameReference("a"), MatchConditionEnd()),
  632. MatchIfStatement(
  633. MatchCondition(MatchNameReference("b"), MatchConditionEnd()),
  634. MatchIfStatement(
  635. MatchCondition(MatchNameReference("c"),
  636. MatchConditionEnd()),
  637. MatchExpressionStatement(MatchNameReference("d")))))),
  638. MatchFileEnd()}));
  639. }
  640. TEST_F(ParseTreeTest, IfElse) {
  641. TokenizedBuffer tokens = GetTokenizedBuffer(
  642. "fn F() {\n"
  643. " if (a)\n"
  644. " if (b)\n"
  645. " c;\n"
  646. " else\n"
  647. " d;\n"
  648. " else\n"
  649. " e;\n"
  650. " if (x) { G(1); }\n"
  651. " else if (x) { G(2); }\n"
  652. " else { G(3); }\n"
  653. "}");
  654. ParseTree tree = ParseTree::Parse(tokens, consumer);
  655. EXPECT_FALSE(tree.HasErrors());
  656. EXPECT_THAT(
  657. tree,
  658. MatchParseTreeNodes(
  659. {MatchFunctionWithBody(
  660. MatchIfStatement(
  661. MatchCondition(MatchNameReference("a"), MatchConditionEnd()),
  662. MatchIfStatement(
  663. MatchCondition(MatchNameReference("b"),
  664. MatchConditionEnd()),
  665. MatchExpressionStatement(MatchNameReference("c")),
  666. MatchIfStatementElse(),
  667. MatchExpressionStatement(MatchNameReference("d"))),
  668. MatchIfStatementElse(),
  669. MatchExpressionStatement(MatchNameReference("e"))),
  670. MatchIfStatement(
  671. MatchCondition(MatchNameReference("x"), MatchConditionEnd()),
  672. MatchCodeBlock(
  673. MatchExpressionStatement(MatchCallExpression(
  674. MatchNameReference("G"), MatchLiteral("1"),
  675. MatchCallExpressionEnd())),
  676. MatchCodeBlockEnd()),
  677. MatchIfStatementElse(),
  678. MatchIfStatement(
  679. MatchCondition(MatchNameReference("x"),
  680. MatchConditionEnd()),
  681. MatchCodeBlock(
  682. MatchExpressionStatement(MatchCallExpression(
  683. MatchNameReference("G"), MatchLiteral("2"),
  684. MatchCallExpressionEnd())),
  685. MatchCodeBlockEnd()),
  686. MatchIfStatementElse(),
  687. MatchCodeBlock(
  688. MatchExpressionStatement(MatchCallExpression(
  689. MatchNameReference("G"), MatchLiteral("3"),
  690. MatchCallExpressionEnd())),
  691. MatchCodeBlockEnd())))),
  692. MatchFileEnd()}));
  693. }
  694. TEST_F(ParseTreeTest, IfError) {
  695. TokenizedBuffer tokens = GetTokenizedBuffer(
  696. "fn F() {\n"
  697. " if a {}\n"
  698. " if () {}\n"
  699. " if (b c) {}\n"
  700. " if (d)\n"
  701. "}");
  702. ParseTree tree = ParseTree::Parse(tokens, consumer);
  703. EXPECT_TRUE(tree.HasErrors());
  704. EXPECT_THAT(
  705. tree,
  706. MatchParseTreeNodes(
  707. {MatchFunctionWithBody(
  708. MatchIfStatement(HasError, MatchNameReference("a"),
  709. MatchCodeBlock(MatchCodeBlockEnd())),
  710. MatchIfStatement(MatchCondition(HasError, MatchConditionEnd()),
  711. MatchCodeBlock(MatchCodeBlockEnd())),
  712. MatchIfStatement(
  713. MatchCondition(HasError, MatchNameReference("b"),
  714. MatchConditionEnd()),
  715. MatchCodeBlock(MatchCodeBlockEnd())),
  716. MatchIfStatement(HasError,
  717. MatchCondition(MatchNameReference("d"),
  718. MatchConditionEnd()))),
  719. MatchFileEnd()}));
  720. }
  721. TEST_F(ParseTreeTest, WhileBreakContinue) {
  722. TokenizedBuffer tokens = GetTokenizedBuffer(
  723. "fn F() {\n"
  724. " while (a) {\n"
  725. " if (b)\n"
  726. " break;\n"
  727. " if (c)\n"
  728. " continue;\n"
  729. "}");
  730. ParseTree tree = ParseTree::Parse(tokens, consumer);
  731. EXPECT_FALSE(tree.HasErrors());
  732. EXPECT_THAT(
  733. tree,
  734. MatchParseTreeNodes(
  735. {MatchFunctionWithBody(MatchWhileStatement(
  736. MatchCondition(MatchNameReference("a"), MatchConditionEnd()),
  737. MatchCodeBlock(
  738. MatchIfStatement(MatchCondition(MatchNameReference("b"),
  739. MatchConditionEnd()),
  740. MatchBreakStatement(MatchStatementEnd())),
  741. MatchIfStatement(
  742. MatchCondition(MatchNameReference("c"),
  743. MatchConditionEnd()),
  744. MatchContinueStatement(MatchStatementEnd())),
  745. MatchCodeBlockEnd()))),
  746. MatchFileEnd()}));
  747. }
  748. TEST_F(ParseTreeTest, Return) {
  749. TokenizedBuffer tokens = GetTokenizedBuffer(
  750. "fn F() {\n"
  751. " if (c)\n"
  752. " return;\n"
  753. "}\n"
  754. "fn G(x: Int) -> Int {\n"
  755. " return x;\n"
  756. "}");
  757. ParseTree tree = ParseTree::Parse(tokens, consumer);
  758. EXPECT_FALSE(tree.HasErrors());
  759. EXPECT_THAT(
  760. tree,
  761. MatchParseTreeNodes(
  762. {MatchFunctionWithBody(MatchIfStatement(
  763. MatchCondition(MatchNameReference("c"), MatchConditionEnd()),
  764. MatchReturnStatement(MatchStatementEnd()))),
  765. MatchFunctionDeclaration(
  766. MatchDeclaredName(),
  767. MatchParameters(MatchPatternBinding(MatchDeclaredName("x"), ":",
  768. MatchNameReference("Int"))),
  769. MatchReturnType(MatchNameReference("Int")),
  770. MatchCodeBlock(MatchReturnStatement(MatchNameReference("x"),
  771. MatchStatementEnd()),
  772. MatchCodeBlockEnd())),
  773. MatchFileEnd()}));
  774. }
  775. auto GetAndDropLine(llvm::StringRef& s) -> std::string {
  776. auto newline_offset = s.find_first_of('\n');
  777. llvm::StringRef line = s.slice(0, newline_offset);
  778. if (newline_offset != llvm::StringRef::npos) {
  779. s = s.substr(newline_offset + 1);
  780. } else {
  781. s = "";
  782. }
  783. return line.str();
  784. }
  785. TEST_F(ParseTreeTest, Printing) {
  786. TokenizedBuffer tokens = GetTokenizedBuffer("fn F();");
  787. ParseTree tree = ParseTree::Parse(tokens, consumer);
  788. EXPECT_FALSE(tree.HasErrors());
  789. std::string print_storage;
  790. llvm::raw_string_ostream print_stream(print_storage);
  791. tree.Print(print_stream);
  792. llvm::StringRef print = print_stream.str();
  793. EXPECT_THAT(GetAndDropLine(print), StrEq("["));
  794. EXPECT_THAT(GetAndDropLine(print),
  795. StrEq("{node_index: 4, kind: 'FunctionDeclaration', text: 'fn', "
  796. "subtree_size: 5, children: ["));
  797. EXPECT_THAT(GetAndDropLine(print),
  798. StrEq(" {node_index: 0, kind: 'DeclaredName', text: 'F'},"));
  799. EXPECT_THAT(GetAndDropLine(print),
  800. StrEq(" {node_index: 2, kind: 'ParameterList', text: '(', "
  801. "subtree_size: 2, children: ["));
  802. EXPECT_THAT(GetAndDropLine(print),
  803. StrEq(" {node_index: 1, kind: 'ParameterListEnd', "
  804. "text: ')'}]},"));
  805. EXPECT_THAT(GetAndDropLine(print),
  806. StrEq(" {node_index: 3, kind: 'DeclarationEnd', text: ';'}]},"));
  807. EXPECT_THAT(GetAndDropLine(print),
  808. StrEq("{node_index: 5, kind: 'FileEnd', text: ''},"));
  809. EXPECT_THAT(GetAndDropLine(print), StrEq("]"));
  810. EXPECT_TRUE(print.empty()) << print;
  811. }
  812. TEST_F(ParseTreeTest, PrintingAsYAML) {
  813. TokenizedBuffer tokens = GetTokenizedBuffer("fn F();");
  814. ParseTree tree = ParseTree::Parse(tokens, consumer);
  815. EXPECT_FALSE(tree.HasErrors());
  816. std::string print_output;
  817. llvm::raw_string_ostream print_stream(print_output);
  818. tree.Print(print_stream);
  819. print_stream.flush();
  820. // Parse the output into a YAML stream. This will print errors to stderr.
  821. llvm::SourceMgr source_manager;
  822. llvm::yaml::Stream yaml_stream(print_output, source_manager);
  823. auto di = yaml_stream.begin();
  824. auto* root_node = llvm::dyn_cast<llvm::yaml::SequenceNode>(di->getRoot());
  825. ASSERT_THAT(root_node, NotNull());
  826. // The root node is just an array of top-level parse nodes.
  827. auto ni = root_node->begin();
  828. auto ne = root_node->end();
  829. auto* node = llvm::dyn_cast<llvm::yaml::MappingNode>(&*ni);
  830. ASSERT_THAT(node, NotNull());
  831. auto nkvi = node->begin();
  832. auto nkve = node->end();
  833. EXPECT_THAT(&*nkvi, IsKeyValueScalars("node_index", "4"));
  834. ++nkvi;
  835. EXPECT_THAT(&*nkvi, IsKeyValueScalars("kind", "FunctionDeclaration"));
  836. ++nkvi;
  837. EXPECT_THAT(&*nkvi, IsKeyValueScalars("text", "fn"));
  838. ++nkvi;
  839. EXPECT_THAT(&*nkvi, IsKeyValueScalars("subtree_size", "5"));
  840. ++nkvi;
  841. auto* children_node = llvm::dyn_cast<llvm::yaml::KeyValueNode>(&*nkvi);
  842. ASSERT_THAT(children_node, NotNull());
  843. auto* children_key_node =
  844. llvm::dyn_cast<llvm::yaml::ScalarNode>(children_node->getKey());
  845. ASSERT_THAT(children_key_node, NotNull());
  846. EXPECT_THAT(children_key_node->getRawValue(), StrEq("children"));
  847. auto* children_value_node =
  848. llvm::dyn_cast<llvm::yaml::SequenceNode>(children_node->getValue());
  849. ASSERT_THAT(children_value_node, NotNull());
  850. auto ci = children_value_node->begin();
  851. auto ce = children_value_node->end();
  852. ASSERT_THAT(ci, Ne(ce));
  853. node = llvm::dyn_cast<llvm::yaml::MappingNode>(&*ci);
  854. ASSERT_THAT(node, NotNull());
  855. auto ckvi = node->begin();
  856. EXPECT_THAT(&*ckvi, IsKeyValueScalars("node_index", "0"));
  857. ++ckvi;
  858. EXPECT_THAT(&*ckvi, IsKeyValueScalars("kind", "DeclaredName"));
  859. ++ckvi;
  860. EXPECT_THAT(&*ckvi, IsKeyValueScalars("text", "F"));
  861. ++ckvi;
  862. EXPECT_THAT(ckvi, Eq(node->end()));
  863. ++ci;
  864. ASSERT_THAT(ci, Ne(ce));
  865. node = llvm::dyn_cast<llvm::yaml::MappingNode>(&*ci);
  866. ASSERT_THAT(node, NotNull());
  867. ckvi = node->begin();
  868. auto ckve = node->end();
  869. EXPECT_THAT(&*ckvi, IsKeyValueScalars("node_index", "2"));
  870. ++ckvi;
  871. EXPECT_THAT(&*ckvi, IsKeyValueScalars("kind", "ParameterList"));
  872. ++ckvi;
  873. EXPECT_THAT(&*ckvi, IsKeyValueScalars("text", "("));
  874. ++ckvi;
  875. EXPECT_THAT(&*ckvi, IsKeyValueScalars("subtree_size", "2"));
  876. ++ckvi;
  877. children_node = llvm::dyn_cast<llvm::yaml::KeyValueNode>(&*ckvi);
  878. ASSERT_THAT(children_node, NotNull());
  879. children_key_node =
  880. llvm::dyn_cast<llvm::yaml::ScalarNode>(children_node->getKey());
  881. ASSERT_THAT(children_key_node, NotNull());
  882. EXPECT_THAT(children_key_node->getRawValue(), StrEq("children"));
  883. children_value_node =
  884. llvm::dyn_cast<llvm::yaml::SequenceNode>(children_node->getValue());
  885. ASSERT_THAT(children_value_node, NotNull());
  886. auto c2_i = children_value_node->begin();
  887. auto c2_e = children_value_node->end();
  888. ASSERT_THAT(c2_i, Ne(c2_e));
  889. node = llvm::dyn_cast<llvm::yaml::MappingNode>(&*c2_i);
  890. ASSERT_THAT(node, NotNull());
  891. auto c2_kvi = node->begin();
  892. EXPECT_THAT(&*c2_kvi, IsKeyValueScalars("node_index", "1"));
  893. ++c2_kvi;
  894. EXPECT_THAT(&*c2_kvi, IsKeyValueScalars("kind", "ParameterListEnd"));
  895. ++c2_kvi;
  896. EXPECT_THAT(&*c2_kvi, IsKeyValueScalars("text", ")"));
  897. ++c2_kvi;
  898. EXPECT_THAT(c2_kvi, Eq(node->end()));
  899. ++c2_i;
  900. EXPECT_THAT(c2_i, Eq(c2_e));
  901. ++ckvi;
  902. EXPECT_THAT(ckvi, Eq(ckve));
  903. ++ci;
  904. ASSERT_THAT(ci, Ne(ce));
  905. node = llvm::dyn_cast<llvm::yaml::MappingNode>(&*ci);
  906. ASSERT_THAT(node, NotNull());
  907. ckvi = node->begin();
  908. EXPECT_THAT(&*ckvi, IsKeyValueScalars("node_index", "3"));
  909. ++ckvi;
  910. EXPECT_THAT(&*ckvi, IsKeyValueScalars("kind", "DeclarationEnd"));
  911. ++ckvi;
  912. EXPECT_THAT(&*ckvi, IsKeyValueScalars("text", ";"));
  913. ++ckvi;
  914. EXPECT_THAT(ckvi, Eq(node->end()));
  915. ++ci;
  916. EXPECT_THAT(ci, Eq(ce));
  917. ++nkvi;
  918. EXPECT_THAT(nkvi, Eq(nkve));
  919. ++ni;
  920. ASSERT_THAT(ni, Ne(ne));
  921. node = llvm::dyn_cast<llvm::yaml::MappingNode>(&*ni);
  922. ASSERT_THAT(node, NotNull());
  923. nkvi = node->begin();
  924. EXPECT_THAT(&*nkvi, IsKeyValueScalars("node_index", "5"));
  925. ++nkvi;
  926. EXPECT_THAT(&*nkvi, IsKeyValueScalars("kind", "FileEnd"));
  927. ++nkvi;
  928. EXPECT_THAT(&*nkvi, IsKeyValueScalars("text", ""));
  929. ++nkvi;
  930. EXPECT_THAT(nkvi, Eq(node->end()));
  931. ++ni;
  932. EXPECT_THAT(ni, Eq(ne));
  933. ++di;
  934. EXPECT_THAT(di, Eq(yaml_stream.end()));
  935. }
  936. } // namespace
  937. } // namespace Carbon