parse_tree_test.cpp 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  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 "toolchain/common/yaml_test_helpers.h"
  11. #include "toolchain/diagnostics/diagnostic_emitter.h"
  12. #include "toolchain/lexer/tokenized_buffer.h"
  13. #include "toolchain/parser/parse_node_kind.h"
  14. #include "toolchain/parser/parse_test_helpers.h"
  15. namespace Carbon {
  16. namespace {
  17. using Carbon::Testing::ExpectedNode;
  18. using Carbon::Testing::MatchParseTreeNodes;
  19. using namespace Carbon::Testing::NodeMatchers;
  20. using ::testing::ElementsAre;
  21. using ::testing::Eq;
  22. using ::testing::Ne;
  23. using ::testing::NotNull;
  24. using ::testing::StrEq;
  25. namespace Yaml = Carbon::Testing::Yaml;
  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. EXPECT_THAT(
  821. Yaml::Value::FromText(print_output),
  822. ElementsAre(Yaml::SequenceValue{
  823. Yaml::MappingValue{
  824. {"node_index", "4"},
  825. {"kind", "FunctionDeclaration"},
  826. {"text", "fn"},
  827. {"subtree_size", "5"},
  828. {"children",
  829. Yaml::SequenceValue{
  830. Yaml::MappingValue{{"node_index", "0"},
  831. {"kind", "DeclaredName"},
  832. {"text", "F"}},
  833. Yaml::MappingValue{{"node_index", "2"},
  834. {"kind", "ParameterList"},
  835. {"text", "("},
  836. {"subtree_size", "2"},
  837. {"children", //
  838. Yaml::SequenceValue{Yaml::MappingValue{
  839. {"node_index", "1"},
  840. {"kind", "ParameterListEnd"},
  841. {"text", ")"}}}}},
  842. Yaml::MappingValue{{"node_index", "3"},
  843. {"kind", "DeclarationEnd"},
  844. {"text", ";"}}}}},
  845. Yaml::MappingValue{{"node_index", "5"}, //
  846. {"kind", "FileEnd"},
  847. {"text", ""}}}));
  848. }
  849. } // namespace
  850. } // namespace Carbon