parse_tree_test.cpp 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296
  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 <gmock/gmock.h>
  6. #include <gtest/gtest.h>
  7. #include <forward_list>
  8. #include "common/ostream.h"
  9. #include "llvm/ADT/Sequence.h"
  10. #include "llvm/Support/FormatVariadic.h"
  11. #include "llvm/Support/SourceMgr.h"
  12. #include "toolchain/common/yaml_test_helpers.h"
  13. #include "toolchain/diagnostics/diagnostic_emitter.h"
  14. #include "toolchain/diagnostics/mocks.h"
  15. #include "toolchain/lexer/tokenized_buffer.h"
  16. #include "toolchain/parser/parse_node_kind.h"
  17. #include "toolchain/parser/parse_test_helpers.h"
  18. namespace Carbon::Testing {
  19. namespace {
  20. using ::testing::AtLeast;
  21. using ::testing::ElementsAre;
  22. using ::testing::Eq;
  23. using ::testing::Ne;
  24. using ::testing::StrEq;
  25. class ParseTreeTest : public ::testing::Test {
  26. protected:
  27. auto GetSourceBuffer(llvm::Twine t) -> SourceBuffer& {
  28. source_storage.push_front(
  29. std::move(*SourceBuffer::CreateFromText(t.str())));
  30. return source_storage.front();
  31. }
  32. auto GetTokenizedBuffer(llvm::Twine t) -> TokenizedBuffer& {
  33. token_storage.push_front(
  34. TokenizedBuffer::Lex(GetSourceBuffer(t), consumer));
  35. return token_storage.front();
  36. }
  37. std::forward_list<SourceBuffer> source_storage;
  38. std::forward_list<TokenizedBuffer> token_storage;
  39. DiagnosticConsumer& consumer = ConsoleDiagnosticConsumer();
  40. };
  41. TEST_F(ParseTreeTest, DefaultInvalid) {
  42. ParseTree::Node node;
  43. EXPECT_FALSE(node.is_valid());
  44. }
  45. TEST_F(ParseTreeTest, IsValid) {
  46. TokenizedBuffer tokens = GetTokenizedBuffer("");
  47. ParseTree tree = ParseTree::Parse(tokens, consumer);
  48. EXPECT_TRUE((*tree.postorder().begin()).is_valid());
  49. }
  50. TEST_F(ParseTreeTest, Empty) {
  51. TokenizedBuffer tokens = GetTokenizedBuffer("");
  52. ParseTree tree = ParseTree::Parse(tokens, consumer);
  53. EXPECT_FALSE(tree.has_errors());
  54. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFileEnd()}));
  55. }
  56. TEST_F(ParseTreeTest, EmptyDeclaration) {
  57. TokenizedBuffer tokens = GetTokenizedBuffer(";");
  58. ParseTree tree = ParseTree::Parse(tokens, consumer);
  59. EXPECT_FALSE(tree.has_errors());
  60. auto it = tree.postorder().begin();
  61. auto end = tree.postorder().end();
  62. ASSERT_THAT(it, Ne(end));
  63. ParseTree::Node n = *it++;
  64. ASSERT_THAT(it, Ne(end));
  65. ParseTree::Node eof = *it++;
  66. EXPECT_THAT(it, Eq(end));
  67. // Directly test the main API so that we get easier to understand errors in
  68. // simple cases than what the custom matcher will produce.
  69. EXPECT_FALSE(tree.node_has_error(n));
  70. EXPECT_FALSE(tree.node_has_error(eof));
  71. EXPECT_THAT(tree.node_kind(n), Eq(ParseNodeKind::EmptyDeclaration()));
  72. EXPECT_THAT(tree.node_kind(eof), Eq(ParseNodeKind::FileEnd()));
  73. auto t = tree.node_token(n);
  74. ASSERT_THAT(tokens.tokens().begin(), Ne(tokens.tokens().end()));
  75. EXPECT_THAT(t, Eq(*tokens.tokens().begin()));
  76. EXPECT_THAT(tokens.GetTokenText(t), Eq(";"));
  77. EXPECT_THAT(tree.children(n).begin(), Eq(tree.children(n).end()));
  78. EXPECT_THAT(tree.children(eof).begin(), Eq(tree.children(eof).end()));
  79. EXPECT_THAT(tree.postorder().begin(), Eq(tree.postorder(n).begin()));
  80. EXPECT_THAT(tree.postorder(n).end(), Eq(tree.postorder(eof).begin()));
  81. EXPECT_THAT(tree.postorder(eof).end(), Eq(tree.postorder().end()));
  82. }
  83. TEST_F(ParseTreeTest, BasicFunctionDeclaration) {
  84. TokenizedBuffer tokens = GetTokenizedBuffer("fn F();");
  85. ParseTree tree = ParseTree::Parse(tokens, consumer);
  86. EXPECT_FALSE(tree.has_errors());
  87. EXPECT_THAT(tree, MatchParseTreeNodes(
  88. {MatchFunctionDeclaration("fn", MatchDeclaredName("F"),
  89. MatchParameters(),
  90. MatchDeclarationEnd(";")),
  91. MatchFileEnd()}));
  92. }
  93. TEST_F(ParseTreeTest, NoDeclarationIntroducerOrSemi) {
  94. TokenizedBuffer tokens = GetTokenizedBuffer("foo bar baz");
  95. ParseTree tree = ParseTree::Parse(tokens, consumer);
  96. EXPECT_TRUE(tree.has_errors());
  97. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFileEnd()}));
  98. }
  99. TEST_F(ParseTreeTest, NoDeclarationIntroducerWithSemi) {
  100. TokenizedBuffer tokens = GetTokenizedBuffer("foo;");
  101. ParseTree tree = ParseTree::Parse(tokens, consumer);
  102. EXPECT_TRUE(tree.has_errors());
  103. EXPECT_THAT(tree, MatchParseTreeNodes({MatchEmptyDeclaration(";", HasError),
  104. MatchFileEnd()}));
  105. }
  106. TEST_F(ParseTreeTest, JustFunctionIntroducerAndSemi) {
  107. TokenizedBuffer tokens = GetTokenizedBuffer("fn;");
  108. ParseTree tree = ParseTree::Parse(tokens, consumer);
  109. EXPECT_TRUE(tree.has_errors());
  110. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFunctionDeclaration(
  111. HasError, MatchDeclarationEnd()),
  112. MatchFileEnd()}));
  113. }
  114. TEST_F(ParseTreeTest, RepeatedFunctionIntroducerAndSemi) {
  115. TokenizedBuffer tokens = GetTokenizedBuffer("fn fn;");
  116. ParseTree tree = ParseTree::Parse(tokens, consumer);
  117. EXPECT_TRUE(tree.has_errors());
  118. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFunctionDeclaration(
  119. HasError, MatchDeclarationEnd()),
  120. MatchFileEnd()}));
  121. }
  122. TEST_F(ParseTreeTest, FunctionDeclarationWithNoSignatureOrSemi) {
  123. TokenizedBuffer tokens = GetTokenizedBuffer("fn foo");
  124. ParseTree tree = ParseTree::Parse(tokens, consumer);
  125. EXPECT_TRUE(tree.has_errors());
  126. EXPECT_THAT(tree,
  127. MatchParseTreeNodes(
  128. {MatchFunctionDeclaration(HasError, MatchDeclaredName("foo")),
  129. MatchFileEnd()}));
  130. }
  131. TEST_F(ParseTreeTest,
  132. FunctionDeclarationWithIdentifierInsteadOfSignatureAndSemi) {
  133. TokenizedBuffer tokens = GetTokenizedBuffer("fn foo bar;");
  134. ParseTree tree = ParseTree::Parse(tokens, consumer);
  135. EXPECT_TRUE(tree.has_errors());
  136. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFunctionDeclaration(
  137. HasError, MatchDeclaredName("foo"),
  138. MatchDeclarationEnd()),
  139. MatchFileEnd()}));
  140. }
  141. TEST_F(ParseTreeTest, FunctionDeclarationWithParameterList) {
  142. TokenizedBuffer tokens = GetTokenizedBuffer("fn foo(bar: i32, baz: i32);");
  143. ParseTree tree = ParseTree::Parse(tokens, consumer);
  144. EXPECT_FALSE(tree.has_errors());
  145. EXPECT_THAT(
  146. tree,
  147. MatchParseTreeNodes(
  148. {MatchFunctionDeclaration(
  149. MatchDeclaredName("foo"),
  150. MatchParameterList(MatchPatternBinding(MatchDeclaredName("bar"),
  151. ":", MatchLiteral("i32")),
  152. MatchParameterListComma(),
  153. MatchPatternBinding(MatchDeclaredName("baz"),
  154. ":", MatchLiteral("i32")),
  155. MatchParameterListEnd()),
  156. MatchDeclarationEnd()),
  157. MatchFileEnd()}));
  158. }
  159. TEST_F(ParseTreeTest, FunctionDefinitionWithParameterList) {
  160. TokenizedBuffer tokens = GetTokenizedBuffer(
  161. "fn foo(bar: i64, baz: i64) {\n"
  162. " foo(baz, bar + baz);\n"
  163. "}");
  164. ParseTree tree = ParseTree::Parse(tokens, consumer);
  165. EXPECT_FALSE(tree.has_errors());
  166. EXPECT_THAT(
  167. tree,
  168. MatchParseTreeNodes(
  169. {MatchFunctionDeclaration(
  170. MatchDeclaredName("foo"),
  171. MatchParameterList(MatchPatternBinding(MatchDeclaredName("bar"),
  172. ":", MatchLiteral("i64")),
  173. MatchParameterListComma(),
  174. MatchPatternBinding(MatchDeclaredName("baz"),
  175. ":", MatchLiteral("i64")),
  176. MatchParameterListEnd()),
  177. MatchCodeBlock(
  178. MatchExpressionStatement(MatchCallExpression(
  179. MatchNameReference("foo"), MatchNameReference("baz"),
  180. MatchCallExpressionComma(),
  181. MatchInfixOperator(MatchNameReference("bar"), "+",
  182. MatchNameReference("baz")),
  183. MatchCallExpressionEnd())),
  184. MatchCodeBlockEnd())),
  185. MatchFileEnd()}));
  186. }
  187. TEST_F(ParseTreeTest, FunctionDeclarationWithReturnType) {
  188. TokenizedBuffer tokens = GetTokenizedBuffer("fn foo() -> u32;");
  189. ParseTree tree = ParseTree::Parse(tokens, consumer);
  190. EXPECT_FALSE(tree.has_errors());
  191. EXPECT_THAT(
  192. tree,
  193. MatchParseTreeNodes(
  194. {MatchFunctionDeclaration(MatchDeclaredName("foo"), MatchParameters(),
  195. MatchReturnType(MatchLiteral("u32")),
  196. MatchDeclarationEnd()),
  197. MatchFileEnd()}));
  198. }
  199. TEST_F(ParseTreeTest, FunctionDefinitionWithReturnType) {
  200. TokenizedBuffer tokens = GetTokenizedBuffer(
  201. "fn foo() -> f64 {\n"
  202. " return 42;\n"
  203. "}");
  204. ParseTree tree = ParseTree::Parse(tokens, consumer);
  205. EXPECT_FALSE(tree.has_errors());
  206. EXPECT_THAT(tree,
  207. MatchParseTreeNodes(
  208. {MatchFunctionDeclaration(
  209. MatchDeclaredName("foo"), MatchParameters(),
  210. MatchReturnType(MatchLiteral("f64")),
  211. MatchCodeBlock(MatchReturnStatement(MatchLiteral("42"),
  212. MatchStatementEnd()),
  213. MatchCodeBlockEnd())),
  214. MatchFileEnd()}));
  215. }
  216. TEST_F(ParseTreeTest, FunctionDeclarationWithSingleIdentifierParameterList) {
  217. TokenizedBuffer tokens = GetTokenizedBuffer("fn foo(bar);");
  218. ParseTree tree = ParseTree::Parse(tokens, consumer);
  219. // Note: this might become valid depending on the parameter syntax, this test
  220. // shouldn't be taken as a sign it should remain invalid.
  221. EXPECT_TRUE(tree.has_errors());
  222. EXPECT_THAT(tree,
  223. MatchParseTreeNodes(
  224. {MatchFunctionDeclaration(
  225. MatchDeclaredName("foo"),
  226. MatchParameterList(HasError, MatchParameterListEnd()),
  227. MatchDeclarationEnd()),
  228. MatchFileEnd()}));
  229. }
  230. TEST_F(ParseTreeTest, FunctionDeclarationWithoutName) {
  231. TokenizedBuffer tokens = GetTokenizedBuffer("fn ();");
  232. ParseTree tree = ParseTree::Parse(tokens, consumer);
  233. EXPECT_TRUE(tree.has_errors());
  234. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFunctionDeclaration(
  235. HasError, MatchDeclarationEnd()),
  236. MatchFileEnd()}));
  237. }
  238. TEST_F(ParseTreeTest,
  239. FunctionDeclarationWithoutNameAndManyTokensToSkipInGroupedSymbols) {
  240. TokenizedBuffer tokens = GetTokenizedBuffer(
  241. "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);");
  242. ParseTree tree = ParseTree::Parse(tokens, consumer);
  243. EXPECT_TRUE(tree.has_errors());
  244. EXPECT_THAT(tree, MatchParseTreeNodes({MatchFunctionDeclaration(
  245. HasError, MatchDeclarationEnd()),
  246. MatchFileEnd()}));
  247. }
  248. TEST_F(ParseTreeTest, FunctionDeclarationSkipToNewlineWithoutSemi) {
  249. TokenizedBuffer tokens = GetTokenizedBuffer(
  250. "fn ()\n"
  251. "fn F();");
  252. ParseTree tree = ParseTree::Parse(tokens, consumer);
  253. EXPECT_TRUE(tree.has_errors());
  254. EXPECT_THAT(
  255. tree, MatchParseTreeNodes({MatchFunctionDeclaration(HasError),
  256. MatchFunctionDeclaration(
  257. MatchDeclaredName("F"), MatchParameters(),
  258. MatchDeclarationEnd()),
  259. MatchFileEnd()}));
  260. }
  261. TEST_F(ParseTreeTest, FunctionDeclarationSkipIndentedNewlineWithSemi) {
  262. TokenizedBuffer tokens = GetTokenizedBuffer(
  263. "fn (x,\n"
  264. " y,\n"
  265. " z);\n"
  266. "fn F();");
  267. ParseTree tree = ParseTree::Parse(tokens, consumer);
  268. EXPECT_TRUE(tree.has_errors());
  269. EXPECT_THAT(
  270. tree,
  271. MatchParseTreeNodes(
  272. {MatchFunctionDeclaration(HasError, MatchDeclarationEnd()),
  273. MatchFunctionDeclaration(MatchDeclaredName("F"), MatchParameters(),
  274. MatchDeclarationEnd()),
  275. MatchFileEnd()}));
  276. }
  277. TEST_F(ParseTreeTest, FunctionDeclarationSkipIndentedNewlineWithoutSemi) {
  278. TokenizedBuffer tokens = GetTokenizedBuffer(
  279. "fn (x,\n"
  280. " y,\n"
  281. " z)\n"
  282. "fn F();");
  283. ParseTree tree = ParseTree::Parse(tokens, consumer);
  284. EXPECT_TRUE(tree.has_errors());
  285. EXPECT_THAT(
  286. tree, MatchParseTreeNodes({MatchFunctionDeclaration(HasError),
  287. MatchFunctionDeclaration(
  288. MatchDeclaredName("F"), MatchParameters(),
  289. MatchDeclarationEnd()),
  290. MatchFileEnd()}));
  291. }
  292. TEST_F(ParseTreeTest, FunctionDeclarationSkipIndentedNewlineUntilOutdent) {
  293. TokenizedBuffer tokens = GetTokenizedBuffer(
  294. " fn (x,\n"
  295. " y,\n"
  296. " z)\n"
  297. "fn F();");
  298. ParseTree tree = ParseTree::Parse(tokens, consumer);
  299. EXPECT_TRUE(tree.has_errors());
  300. EXPECT_THAT(
  301. tree, MatchParseTreeNodes({MatchFunctionDeclaration(HasError),
  302. MatchFunctionDeclaration(
  303. MatchDeclaredName("F"), MatchParameters(),
  304. MatchDeclarationEnd()),
  305. MatchFileEnd()}));
  306. }
  307. TEST_F(ParseTreeTest, FunctionDeclarationSkipWithoutSemiToCurly) {
  308. // FIXME: We don't have a grammar construct that uses curlies yet so this just
  309. // won't parse at all. Once it does, we should ensure that the close brace
  310. // gets properly parsed for the struct (or whatever other curly-braced syntax
  311. // we have grouping function declarations) despite the invalid function
  312. // declaration missing a semicolon.
  313. TokenizedBuffer tokens = GetTokenizedBuffer(
  314. "struct X { fn () }\n"
  315. "fn F();");
  316. ParseTree tree = ParseTree::Parse(tokens, consumer);
  317. EXPECT_TRUE(tree.has_errors());
  318. }
  319. TEST_F(ParseTreeTest, BasicFunctionDefinition) {
  320. TokenizedBuffer tokens = GetTokenizedBuffer(
  321. "fn F() {\n"
  322. "}");
  323. ParseTree tree = ParseTree::Parse(tokens, consumer);
  324. EXPECT_FALSE(tree.has_errors());
  325. EXPECT_THAT(tree, MatchParseTreeNodes(
  326. {MatchFunctionDeclaration(
  327. MatchDeclaredName("F"), MatchParameters(),
  328. MatchCodeBlock("{", MatchCodeBlockEnd("}"))),
  329. MatchFileEnd()}));
  330. }
  331. TEST_F(ParseTreeTest, FunctionDefinitionWithIdenifierInStatements) {
  332. TokenizedBuffer tokens = GetTokenizedBuffer(
  333. "fn F() {\n"
  334. " bar\n"
  335. "}");
  336. ParseTree tree = ParseTree::Parse(tokens, consumer);
  337. // Note: this might become valid depending on the expression syntax. This test
  338. // shouldn't be taken as a sign it should remain invalid.
  339. EXPECT_TRUE(tree.has_errors());
  340. EXPECT_THAT(tree, MatchParseTreeNodes(
  341. {MatchFunctionDeclaration(
  342. MatchDeclaredName("F"), MatchParameters(),
  343. MatchCodeBlock(HasError, MatchNameReference("bar"),
  344. MatchCodeBlockEnd())),
  345. MatchFileEnd()}));
  346. }
  347. TEST_F(ParseTreeTest, FunctionDefinitionWithFunctionCall) {
  348. TokenizedBuffer tokens = GetTokenizedBuffer(
  349. "fn F() {\n"
  350. " a.b.f(c.d, (e)).g();\n"
  351. "}");
  352. ParseTree tree = ParseTree::Parse(tokens, consumer);
  353. EXPECT_FALSE(tree.has_errors());
  354. ExpectedNode call_to_f = MatchCallExpression(
  355. MatchDesignator(MatchDesignator(MatchNameReference("a"), "b"), "f"),
  356. MatchDesignator(MatchNameReference("c"), "d"), MatchCallExpressionComma(),
  357. MatchParenExpression(MatchNameReference("e"), MatchParenExpressionEnd()),
  358. MatchCallExpressionEnd());
  359. ExpectedNode statement = MatchExpressionStatement(MatchCallExpression(
  360. MatchDesignator(call_to_f, "g"), MatchCallExpressionEnd()));
  361. EXPECT_THAT(tree, MatchParseTreeNodes(
  362. {MatchFunctionWithBody(statement), MatchFileEnd()}));
  363. }
  364. TEST_F(ParseTreeTest, InvalidDesignators) {
  365. TokenizedBuffer tokens = GetTokenizedBuffer(
  366. "fn F() {\n"
  367. " a.;\n"
  368. " a.fn;\n"
  369. " a.42;\n"
  370. "}");
  371. ParseTree tree = ParseTree::Parse(tokens, consumer);
  372. EXPECT_TRUE(tree.has_errors());
  373. EXPECT_THAT(tree, MatchParseTreeNodes(
  374. {MatchFunctionWithBody(
  375. MatchExpressionStatement(
  376. MatchDesignatorExpression(
  377. MatchNameReference("a"), ".", HasError),
  378. HasError, ";"),
  379. MatchExpressionStatement(
  380. MatchDesignatorExpression(
  381. MatchNameReference("a"), ".",
  382. MatchDesignatedName("fn", HasError)),
  383. ";"),
  384. MatchExpressionStatement(
  385. MatchDesignatorExpression(
  386. MatchNameReference("a"), ".", HasError),
  387. HasError, ";")),
  388. MatchFileEnd()}));
  389. }
  390. TEST_F(ParseTreeTest, Operators) {
  391. TokenizedBuffer tokens = GetTokenizedBuffer(
  392. "fn F() {\n"
  393. " n = a * b + c * d = d * d << e & f - not g;\n"
  394. "}");
  395. ParseTree tree = ParseTree::Parse(tokens, consumer);
  396. EXPECT_TRUE(tree.has_errors());
  397. EXPECT_THAT(
  398. tree,
  399. MatchParseTreeNodes(
  400. {MatchFunctionWithBody(MatchExpressionStatement(MatchInfixOperator(
  401. MatchNameReference("n"), "=",
  402. MatchInfixOperator(
  403. MatchInfixOperator(
  404. MatchInfixOperator(MatchNameReference("a"), "*",
  405. MatchNameReference("b")),
  406. "+",
  407. MatchInfixOperator(MatchNameReference("c"), "*",
  408. MatchNameReference("d"))),
  409. "=",
  410. MatchInfixOperator(
  411. HasError,
  412. MatchInfixOperator(
  413. HasError,
  414. MatchInfixOperator(
  415. HasError,
  416. MatchInfixOperator(MatchNameReference("d"), "*",
  417. MatchNameReference("d")),
  418. "<<", MatchNameReference("e")),
  419. "&", MatchNameReference("f")),
  420. "-",
  421. MatchPrefixOperator("not", MatchNameReference("g"))))))),
  422. MatchFileEnd()}));
  423. }
  424. TEST_F(ParseTreeTest, OperatorsPrefixUnary) {
  425. TokenizedBuffer tokens = GetTokenizedBuffer(
  426. "fn F() {\n"
  427. " ++++n;\n"
  428. "}");
  429. ParseTree tree = ParseTree::Parse(tokens, consumer);
  430. EXPECT_FALSE(tree.has_errors());
  431. EXPECT_THAT(
  432. tree,
  433. MatchParseTreeNodes(
  434. {MatchFunctionWithBody(MatchExpressionStatement(MatchPrefixOperator(
  435. "++", MatchPrefixOperator("++", MatchNameReference("n"))))),
  436. MatchFileEnd()}));
  437. }
  438. TEST_F(ParseTreeTest, OperatorsPostfixUnary) {
  439. TokenizedBuffer tokens = GetTokenizedBuffer(
  440. "fn F() {\n"
  441. " n++++;\n"
  442. "}");
  443. ParseTree tree = ParseTree::Parse(tokens, consumer);
  444. EXPECT_FALSE(tree.has_errors());
  445. EXPECT_THAT(
  446. tree,
  447. MatchParseTreeNodes(
  448. {MatchFunctionWithBody(MatchExpressionStatement(MatchPostfixOperator(
  449. MatchPostfixOperator(MatchNameReference("n"), "++"), "++"))),
  450. MatchFileEnd()}));
  451. }
  452. TEST_F(ParseTreeTest, OperatorsAssociative) {
  453. TokenizedBuffer tokens = GetTokenizedBuffer(
  454. "fn F() {\n"
  455. " a and b and c;\n"
  456. "}");
  457. ParseTree tree = ParseTree::Parse(tokens, consumer);
  458. EXPECT_FALSE(tree.has_errors());
  459. EXPECT_THAT(
  460. tree,
  461. MatchParseTreeNodes(
  462. {MatchFunctionWithBody(MatchExpressionStatement(MatchInfixOperator(
  463. MatchInfixOperator(MatchNameReference("a"), "and",
  464. MatchNameReference("b")),
  465. "and", MatchNameReference("c")))),
  466. MatchFileEnd()}));
  467. }
  468. TEST_F(ParseTreeTest, OperatorsMissingPrecedence1) {
  469. TokenizedBuffer tokens = GetTokenizedBuffer(
  470. "fn F() {\n"
  471. " a and b or c;\n"
  472. "}");
  473. ParseTree tree = ParseTree::Parse(tokens, consumer);
  474. EXPECT_TRUE(tree.has_errors());
  475. EXPECT_THAT(
  476. tree,
  477. MatchParseTreeNodes(
  478. {MatchFunctionWithBody(MatchExpressionStatement(MatchInfixOperator(
  479. HasError,
  480. MatchInfixOperator(MatchNameReference("a"), "and",
  481. MatchNameReference("b")),
  482. "or", MatchNameReference("c")))),
  483. MatchFileEnd()}));
  484. }
  485. TEST_F(ParseTreeTest, OperatorsMissingPrecedence2) {
  486. TokenizedBuffer tokens = GetTokenizedBuffer(
  487. "fn F() {\n"
  488. " a or b and c;\n"
  489. "}");
  490. ParseTree tree = ParseTree::Parse(tokens, consumer);
  491. EXPECT_TRUE(tree.has_errors());
  492. EXPECT_THAT(
  493. tree,
  494. MatchParseTreeNodes(
  495. {MatchFunctionWithBody(MatchExpressionStatement(MatchInfixOperator(
  496. HasError,
  497. MatchInfixOperator(MatchNameReference("a"), "or",
  498. MatchNameReference("b")),
  499. "and", MatchNameReference("c")))),
  500. MatchFileEnd()}));
  501. }
  502. TEST_F(ParseTreeTest, OperatorsMissingPrecedenceForNot) {
  503. TokenizedBuffer tokens = GetTokenizedBuffer(
  504. "fn F() {\n"
  505. " not a and not b and not c;\n"
  506. "}");
  507. ParseTree tree = ParseTree::Parse(tokens, consumer);
  508. EXPECT_FALSE(tree.has_errors());
  509. EXPECT_THAT(
  510. tree,
  511. MatchParseTreeNodes(
  512. {MatchFunctionWithBody(MatchExpressionStatement(MatchInfixOperator(
  513. MatchInfixOperator(
  514. MatchPrefixOperator("not", MatchNameReference("a")), "and",
  515. MatchPrefixOperator("not", MatchNameReference("b"))),
  516. "and", MatchPrefixOperator("not", MatchNameReference("c"))))),
  517. MatchFileEnd()}));
  518. }
  519. TEST_F(ParseTreeTest, OperatorFixity) {
  520. TokenizedBuffer tokens = GetTokenizedBuffer(
  521. "fn F(p: i32*, n: i32) {\n"
  522. " var q: i32* = p;\n"
  523. " var t: Type = i32*;\n"
  524. " t = t**;\n"
  525. " n = n * n;\n"
  526. " n = n * *p;\n"
  527. " n = n*n;\n"
  528. " G(i32*, n * n);\n"
  529. "}");
  530. ParseTree tree = ParseTree::Parse(tokens, consumer);
  531. EXPECT_FALSE(tree.has_errors());
  532. EXPECT_THAT(
  533. tree,
  534. MatchParseTreeNodes(
  535. {MatchFunctionDeclaration(
  536. MatchDeclaredName("F"),
  537. MatchParameters(
  538. MatchPatternBinding(
  539. MatchDeclaredName("p"),
  540. MatchPostfixOperator(MatchLiteral("i32"), "*")),
  541. MatchParameterListComma(),
  542. MatchPatternBinding(MatchDeclaredName("n"),
  543. MatchLiteral("i32"))),
  544. MatchCodeBlock(
  545. MatchVariableDeclaration(
  546. MatchPatternBinding(
  547. MatchDeclaredName("q"),
  548. MatchPostfixOperator(MatchLiteral("i32"), "*")),
  549. MatchVariableInitializer(MatchNameReference("p")),
  550. MatchDeclarationEnd()),
  551. MatchVariableDeclaration(
  552. MatchPatternBinding(MatchDeclaredName("t"),
  553. MatchNameReference("Type")),
  554. MatchVariableInitializer(
  555. MatchPostfixOperator(MatchLiteral("i32"), "*")),
  556. MatchDeclarationEnd()),
  557. MatchExpressionStatement(MatchInfixOperator(
  558. MatchNameReference("t"), "=",
  559. MatchPostfixOperator(
  560. MatchPostfixOperator(MatchNameReference("t"), "*"),
  561. "*"))),
  562. MatchExpressionStatement(MatchInfixOperator(
  563. MatchNameReference("n"), "=",
  564. MatchInfixOperator(MatchNameReference("n"), "*",
  565. MatchNameReference("n")))),
  566. MatchExpressionStatement(MatchInfixOperator(
  567. MatchNameReference("n"), "=",
  568. MatchInfixOperator(
  569. MatchNameReference("n"), "*",
  570. MatchPrefixOperator("*", MatchNameReference("p"))))),
  571. MatchExpressionStatement(MatchInfixOperator(
  572. MatchNameReference("n"), "=",
  573. MatchInfixOperator(MatchNameReference("n"), "*",
  574. MatchNameReference("n")))),
  575. MatchExpressionStatement(MatchCallExpression(
  576. MatchNameReference("G"),
  577. MatchPostfixOperator(MatchLiteral("i32"), "*"),
  578. MatchCallExpressionComma(),
  579. MatchInfixOperator(MatchNameReference("n"), "*",
  580. MatchNameReference("n")),
  581. MatchCallExpressionEnd())),
  582. MatchCodeBlockEnd())),
  583. MatchFileEnd()}));
  584. }
  585. TEST_F(ParseTreeTest, OperatorWhitespaceErrors) {
  586. // Test dispositions: Recovered means we issued an error but recovered a
  587. // proper parse tree; Failed means we didn't fully recover from the error.
  588. enum Kind { Valid, Recovered, Failed };
  589. struct Testcase {
  590. const char* input;
  591. Kind kind;
  592. } testcases[] = {
  593. {"var v: Type = i8*;", Valid},
  594. {"var v: Type = i8 *;", Recovered},
  595. {"var v: Type = i8* ;", Valid},
  596. {"var v: Type = i8 * ;", Recovered},
  597. {"var n: i8 = n * n;", Valid},
  598. {"var n: i8 = n*n;", Valid},
  599. {"var n: i8 = (n)*3;", Valid},
  600. {"var n: i8 = 3*(n);", Valid},
  601. {"var n: i8 = n *n;", Recovered},
  602. // FIXME: We could figure out that this first Failed example is infix
  603. // with one-token lookahead.
  604. {"var n: i8 = n* n;", Failed},
  605. {"var n: i8 = n* -n;", Failed},
  606. {"var n: i8 = n* *p;", Failed},
  607. // FIXME: We try to form (n*)*p and reject due to missing parentheses
  608. // before we notice the missing whitespace around the second `*`.
  609. // It'd be better to (somehow) form n*(*p) and reject due to the missing
  610. // whitespace around the first `*`.
  611. {"var n: i8 = n**p;", Failed},
  612. {"var n: i8 = -n;", Valid},
  613. {"var n: i8 = - n;", Recovered},
  614. {"var n: i8 =-n;", Valid},
  615. {"var n: i8 =- n;", Recovered},
  616. {"var n: i8 = F(i8 *);", Recovered},
  617. {"var n: i8 = F(i8 *, 0);", Recovered},
  618. };
  619. for (auto [input, kind] : testcases) {
  620. TokenizedBuffer tokens = GetTokenizedBuffer(input);
  621. ErrorTrackingDiagnosticConsumer error_tracker(consumer);
  622. ParseTree tree = ParseTree::Parse(tokens, error_tracker);
  623. EXPECT_THAT(tree.has_errors(), Eq(kind == Failed)) << input;
  624. EXPECT_THAT(error_tracker.seen_error(), Eq(kind != Valid)) << input;
  625. }
  626. }
  627. TEST_F(ParseTreeTest, VariableDeclarations) {
  628. TokenizedBuffer tokens = GetTokenizedBuffer(
  629. "var v: i32 = 0;\n"
  630. "var w: i32;\n"
  631. "fn F() {\n"
  632. " var s: String = \"hello\";\n"
  633. "}");
  634. ParseTree tree = ParseTree::Parse(tokens, consumer);
  635. EXPECT_FALSE(tree.has_errors());
  636. EXPECT_THAT(tree,
  637. MatchParseTreeNodes(
  638. {MatchVariableDeclaration(
  639. MatchPatternBinding(MatchDeclaredName("v"), ":",
  640. MatchLiteral("i32")),
  641. MatchVariableInitializer(MatchLiteral("0")),
  642. MatchDeclarationEnd()),
  643. MatchVariableDeclaration(
  644. MatchPatternBinding(MatchDeclaredName("w"), ":",
  645. MatchLiteral("i32")),
  646. MatchDeclarationEnd()),
  647. MatchFunctionWithBody(MatchVariableDeclaration(
  648. MatchPatternBinding(MatchDeclaredName("s"), ":",
  649. MatchNameReference("String")),
  650. MatchVariableInitializer(MatchLiteral("\"hello\"")),
  651. MatchDeclarationEnd())),
  652. MatchFileEnd()}));
  653. }
  654. TEST_F(ParseTreeTest, IfNoElse) {
  655. TokenizedBuffer tokens = GetTokenizedBuffer(
  656. "fn F() {\n"
  657. " if (a) {\n"
  658. " if (b) {\n"
  659. " if (c) {\n"
  660. " d;\n"
  661. " }\n"
  662. " }\n"
  663. " }\n"
  664. "}");
  665. ErrorTrackingDiagnosticConsumer error_tracker(consumer);
  666. ParseTree tree = ParseTree::Parse(tokens, error_tracker);
  667. EXPECT_FALSE(tree.has_errors());
  668. EXPECT_FALSE(error_tracker.seen_error());
  669. EXPECT_THAT(
  670. tree,
  671. MatchParseTreeNodes(
  672. {MatchFunctionWithBody(MatchIfStatement(
  673. MatchCondition(MatchNameReference("a"), MatchConditionEnd()),
  674. MatchCodeBlock(
  675. MatchIfStatement(
  676. MatchCondition(MatchNameReference("b"),
  677. MatchConditionEnd()),
  678. MatchCodeBlock(
  679. MatchIfStatement(
  680. MatchCondition(MatchNameReference("c"),
  681. MatchConditionEnd()),
  682. MatchCodeBlock(MatchExpressionStatement(
  683. MatchNameReference("d")),
  684. MatchCodeBlockEnd())),
  685. MatchCodeBlockEnd())),
  686. MatchCodeBlockEnd()))),
  687. MatchFileEnd()}));
  688. }
  689. TEST_F(ParseTreeTest, IfNoElseUnbraced) {
  690. TokenizedBuffer tokens = GetTokenizedBuffer(
  691. "fn F() {\n"
  692. " if (a)\n"
  693. " if (b)\n"
  694. " if (c)\n"
  695. " d;\n"
  696. "}");
  697. ErrorTrackingDiagnosticConsumer error_tracker(consumer);
  698. ParseTree tree = ParseTree::Parse(tokens, error_tracker);
  699. // The missing braces are invalid, but we should be able to recover.
  700. EXPECT_FALSE(tree.has_errors());
  701. EXPECT_TRUE(error_tracker.seen_error());
  702. EXPECT_THAT(
  703. tree,
  704. MatchParseTreeNodes(
  705. {MatchFunctionWithBody(MatchIfStatement(
  706. MatchCondition(MatchNameReference("a"), MatchConditionEnd()),
  707. MatchIfStatement(
  708. MatchCondition(MatchNameReference("b"), MatchConditionEnd()),
  709. MatchIfStatement(
  710. MatchCondition(MatchNameReference("c"),
  711. MatchConditionEnd()),
  712. MatchExpressionStatement(MatchNameReference("d")))))),
  713. MatchFileEnd()}));
  714. }
  715. TEST_F(ParseTreeTest, IfElse) {
  716. TokenizedBuffer tokens = GetTokenizedBuffer(
  717. "fn F() {\n"
  718. " if (a) {\n"
  719. " if (b) {\n"
  720. " c;\n"
  721. " } else {\n"
  722. " d;\n"
  723. " }\n"
  724. " } else {\n"
  725. " e;\n"
  726. " }\n"
  727. " if (x) { G(1); }\n"
  728. " else if (x) { G(2); }\n"
  729. " else { G(3); }\n"
  730. "}");
  731. ErrorTrackingDiagnosticConsumer error_tracker(consumer);
  732. ParseTree tree = ParseTree::Parse(tokens, error_tracker);
  733. EXPECT_FALSE(tree.has_errors());
  734. EXPECT_FALSE(error_tracker.seen_error());
  735. EXPECT_THAT(
  736. tree,
  737. MatchParseTreeNodes(
  738. {MatchFunctionWithBody(
  739. MatchIfStatement(
  740. MatchCondition(MatchNameReference("a"), MatchConditionEnd()),
  741. MatchCodeBlock(
  742. MatchIfStatement(
  743. MatchCondition(MatchNameReference("b"),
  744. MatchConditionEnd()),
  745. MatchCodeBlock(MatchExpressionStatement(
  746. MatchNameReference("c")),
  747. MatchCodeBlockEnd()),
  748. MatchIfStatementElse(),
  749. MatchCodeBlock(MatchExpressionStatement(
  750. MatchNameReference("d")),
  751. MatchCodeBlockEnd())),
  752. MatchCodeBlockEnd()),
  753. MatchIfStatementElse(),
  754. MatchCodeBlock(
  755. MatchExpressionStatement(MatchNameReference("e")),
  756. MatchCodeBlockEnd())),
  757. MatchIfStatement(
  758. MatchCondition(MatchNameReference("x"), MatchConditionEnd()),
  759. MatchCodeBlock(
  760. MatchExpressionStatement(MatchCallExpression(
  761. MatchNameReference("G"), MatchLiteral("1"),
  762. MatchCallExpressionEnd())),
  763. MatchCodeBlockEnd()),
  764. MatchIfStatementElse(),
  765. MatchIfStatement(
  766. MatchCondition(MatchNameReference("x"),
  767. MatchConditionEnd()),
  768. MatchCodeBlock(
  769. MatchExpressionStatement(MatchCallExpression(
  770. MatchNameReference("G"), MatchLiteral("2"),
  771. MatchCallExpressionEnd())),
  772. MatchCodeBlockEnd()),
  773. MatchIfStatementElse(),
  774. MatchCodeBlock(
  775. MatchExpressionStatement(MatchCallExpression(
  776. MatchNameReference("G"), MatchLiteral("3"),
  777. MatchCallExpressionEnd())),
  778. MatchCodeBlockEnd())))),
  779. MatchFileEnd()}));
  780. }
  781. TEST_F(ParseTreeTest, IfElseUnbraced) {
  782. TokenizedBuffer tokens = GetTokenizedBuffer(
  783. "fn F() {\n"
  784. " if (a)\n"
  785. " if (b)\n"
  786. " c;\n"
  787. " else\n"
  788. " d;\n"
  789. " else\n"
  790. " e;\n"
  791. " if (x) { G(1); }\n"
  792. " else if (x) { G(2); }\n"
  793. " else { G(3); }\n"
  794. "}");
  795. ErrorTrackingDiagnosticConsumer error_tracker(consumer);
  796. ParseTree tree = ParseTree::Parse(tokens, error_tracker);
  797. // The missing braces are invalid, but we should be able to recover.
  798. EXPECT_FALSE(tree.has_errors());
  799. EXPECT_TRUE(error_tracker.seen_error());
  800. EXPECT_THAT(
  801. tree,
  802. MatchParseTreeNodes(
  803. {MatchFunctionWithBody(
  804. MatchIfStatement(
  805. MatchCondition(MatchNameReference("a"), MatchConditionEnd()),
  806. MatchIfStatement(
  807. MatchCondition(MatchNameReference("b"),
  808. MatchConditionEnd()),
  809. MatchExpressionStatement(MatchNameReference("c")),
  810. MatchIfStatementElse(),
  811. MatchExpressionStatement(MatchNameReference("d"))),
  812. MatchIfStatementElse(),
  813. MatchExpressionStatement(MatchNameReference("e"))),
  814. MatchIfStatement(
  815. MatchCondition(MatchNameReference("x"), MatchConditionEnd()),
  816. MatchCodeBlock(
  817. MatchExpressionStatement(MatchCallExpression(
  818. MatchNameReference("G"), MatchLiteral("1"),
  819. MatchCallExpressionEnd())),
  820. MatchCodeBlockEnd()),
  821. MatchIfStatementElse(),
  822. MatchIfStatement(
  823. MatchCondition(MatchNameReference("x"),
  824. MatchConditionEnd()),
  825. MatchCodeBlock(
  826. MatchExpressionStatement(MatchCallExpression(
  827. MatchNameReference("G"), MatchLiteral("2"),
  828. MatchCallExpressionEnd())),
  829. MatchCodeBlockEnd()),
  830. MatchIfStatementElse(),
  831. MatchCodeBlock(
  832. MatchExpressionStatement(MatchCallExpression(
  833. MatchNameReference("G"), MatchLiteral("3"),
  834. MatchCallExpressionEnd())),
  835. MatchCodeBlockEnd())))),
  836. MatchFileEnd()}));
  837. }
  838. TEST_F(ParseTreeTest, IfError) {
  839. TokenizedBuffer tokens = GetTokenizedBuffer(
  840. "fn F() {\n"
  841. " if a {}\n"
  842. " if () {}\n"
  843. " if (b c) {}\n"
  844. " if (d)\n"
  845. "}");
  846. ParseTree tree = ParseTree::Parse(tokens, consumer);
  847. EXPECT_TRUE(tree.has_errors());
  848. EXPECT_THAT(
  849. tree,
  850. MatchParseTreeNodes(
  851. {MatchFunctionWithBody(
  852. MatchIfStatement(HasError, MatchNameReference("a"),
  853. MatchCodeBlock(MatchCodeBlockEnd())),
  854. MatchIfStatement(MatchCondition(HasError, MatchConditionEnd()),
  855. MatchCodeBlock(MatchCodeBlockEnd())),
  856. MatchIfStatement(
  857. MatchCondition(HasError, MatchNameReference("b"),
  858. MatchConditionEnd()),
  859. MatchCodeBlock(MatchCodeBlockEnd())),
  860. MatchIfStatement(HasError,
  861. MatchCondition(MatchNameReference("d"),
  862. MatchConditionEnd()))),
  863. MatchFileEnd()}));
  864. }
  865. TEST_F(ParseTreeTest, WhileBreakContinue) {
  866. TokenizedBuffer tokens = GetTokenizedBuffer(
  867. "fn F() {\n"
  868. " while (a) {\n"
  869. " if (b) {\n"
  870. " break;\n"
  871. " }\n"
  872. " if (c) {\n"
  873. " continue;\n"
  874. " }\n"
  875. "}");
  876. ErrorTrackingDiagnosticConsumer error_tracker(consumer);
  877. ParseTree tree = ParseTree::Parse(tokens, error_tracker);
  878. EXPECT_FALSE(tree.has_errors());
  879. EXPECT_FALSE(error_tracker.seen_error());
  880. EXPECT_THAT(
  881. tree,
  882. MatchParseTreeNodes(
  883. {MatchFunctionWithBody(MatchWhileStatement(
  884. MatchCondition(MatchNameReference("a"), MatchConditionEnd()),
  885. MatchCodeBlock(
  886. MatchIfStatement(
  887. MatchCondition(MatchNameReference("b"),
  888. MatchConditionEnd()),
  889. MatchCodeBlock(MatchBreakStatement(MatchStatementEnd()),
  890. MatchCodeBlockEnd())),
  891. MatchIfStatement(MatchCondition(MatchNameReference("c"),
  892. MatchConditionEnd()),
  893. MatchCodeBlock(MatchContinueStatement(
  894. MatchStatementEnd()),
  895. MatchCodeBlockEnd())),
  896. MatchCodeBlockEnd()))),
  897. MatchFileEnd()}));
  898. }
  899. TEST_F(ParseTreeTest, WhileUnbraced) {
  900. TokenizedBuffer tokens = GetTokenizedBuffer(
  901. "fn F() {\n"
  902. " while (a) \n"
  903. " break;\n"
  904. "}");
  905. ErrorTrackingDiagnosticConsumer error_tracker(consumer);
  906. ParseTree tree = ParseTree::Parse(tokens, error_tracker);
  907. EXPECT_FALSE(tree.has_errors());
  908. EXPECT_TRUE(error_tracker.seen_error());
  909. EXPECT_THAT(
  910. tree,
  911. MatchParseTreeNodes(
  912. {MatchFunctionWithBody(MatchWhileStatement(
  913. MatchCondition(MatchNameReference("a"), MatchConditionEnd()),
  914. MatchBreakStatement(MatchStatementEnd()))),
  915. MatchFileEnd()}));
  916. }
  917. TEST_F(ParseTreeTest, Return) {
  918. TokenizedBuffer tokens = GetTokenizedBuffer(
  919. "fn F() {\n"
  920. " if (c) {\n"
  921. " return;\n"
  922. " }\n"
  923. "}\n"
  924. "fn G(x: Foo) -> Foo {\n"
  925. " return x;\n"
  926. "}");
  927. ParseTree tree = ParseTree::Parse(tokens, consumer);
  928. EXPECT_FALSE(tree.has_errors());
  929. EXPECT_THAT(
  930. tree,
  931. MatchParseTreeNodes(
  932. {MatchFunctionWithBody(MatchIfStatement(
  933. MatchCondition(MatchNameReference("c"), MatchConditionEnd()),
  934. MatchCodeBlock(MatchReturnStatement(MatchStatementEnd()),
  935. MatchCodeBlockEnd()))),
  936. MatchFunctionDeclaration(
  937. MatchDeclaredName(),
  938. MatchParameters(MatchPatternBinding(MatchDeclaredName("x"), ":",
  939. MatchNameReference("Foo"))),
  940. MatchReturnType(MatchNameReference("Foo")),
  941. MatchCodeBlock(MatchReturnStatement(MatchNameReference("x"),
  942. MatchStatementEnd()),
  943. MatchCodeBlockEnd())),
  944. MatchFileEnd()}));
  945. }
  946. TEST_F(ParseTreeTest, Tuples) {
  947. TokenizedBuffer tokens = GetTokenizedBuffer(R"(
  948. var x: (i32, i32) = (1, 2);
  949. var y: ((), (), ());
  950. )");
  951. ParseTree tree = ParseTree::Parse(tokens, consumer);
  952. EXPECT_FALSE(tree.has_errors());
  953. auto empty_tuple = MatchTupleLiteral(MatchTupleLiteralEnd());
  954. EXPECT_THAT(
  955. tree,
  956. MatchParseTreeNodes(
  957. {MatchVariableDeclaration(
  958. MatchPatternBinding(MatchDeclaredName("x"), ":",
  959. MatchTupleLiteral(MatchLiteral("i32"),
  960. MatchTupleLiteralComma(),
  961. MatchLiteral("i32"),
  962. MatchTupleLiteralEnd())),
  963. MatchVariableInitializer(MatchTupleLiteral(
  964. MatchLiteral("1"), MatchTupleLiteralComma(),
  965. MatchLiteral("2"), MatchTupleLiteralEnd())),
  966. MatchDeclarationEnd()),
  967. MatchVariableDeclaration(
  968. MatchPatternBinding(
  969. MatchDeclaredName("y"), ":",
  970. MatchTupleLiteral(empty_tuple, MatchTupleLiteralComma(),
  971. empty_tuple, MatchTupleLiteralComma(),
  972. empty_tuple, MatchTupleLiteralEnd())),
  973. MatchDeclarationEnd()),
  974. MatchFileEnd()}));
  975. }
  976. TEST_F(ParseTreeTest, Structs) {
  977. TokenizedBuffer tokens = GetTokenizedBuffer(R"(
  978. var x: {.a: i32, .b: i32} = {.a = 1, .b = 2};
  979. var y: {} = {};
  980. var z: {.n: i32,} = {.n = 4,};
  981. )");
  982. ParseTree tree = ParseTree::Parse(tokens, consumer);
  983. EXPECT_FALSE(tree.has_errors());
  984. EXPECT_THAT(
  985. tree,
  986. MatchParseTreeNodes(
  987. {MatchVariableDeclaration(
  988. MatchPatternBinding(
  989. MatchDeclaredName("x"), ":",
  990. MatchStructTypeLiteral(
  991. MatchStructFieldType(MatchStructFieldDesignator(
  992. ".", MatchDesignatedName("a")),
  993. ":", MatchLiteral("i32")),
  994. MatchStructComma(),
  995. MatchStructFieldType(MatchStructFieldDesignator(
  996. ".", MatchDesignatedName("b")),
  997. ":", MatchLiteral("i32")),
  998. MatchStructEnd())),
  999. MatchVariableInitializer(MatchStructLiteral(
  1000. MatchStructFieldValue(MatchStructFieldDesignator(
  1001. ".", MatchDesignatedName("a")),
  1002. "=", MatchLiteral("1")),
  1003. MatchStructComma(),
  1004. MatchStructFieldValue(MatchStructFieldDesignator(
  1005. ".", MatchDesignatedName("b")),
  1006. "=", MatchLiteral("2")),
  1007. MatchStructEnd())),
  1008. MatchDeclarationEnd()),
  1009. MatchVariableDeclaration(
  1010. MatchPatternBinding(MatchDeclaredName("y"), ":",
  1011. MatchStructLiteral(MatchStructEnd())),
  1012. MatchVariableInitializer(MatchStructLiteral(MatchStructEnd())),
  1013. MatchDeclarationEnd()),
  1014. MatchVariableDeclaration(
  1015. MatchPatternBinding(
  1016. MatchDeclaredName("z"), ":",
  1017. MatchStructTypeLiteral(
  1018. MatchStructFieldType(MatchStructFieldDesignator(
  1019. ".", MatchDesignatedName("n")),
  1020. ":", MatchLiteral("i32")),
  1021. MatchStructComma(), MatchStructEnd())),
  1022. MatchVariableInitializer(MatchStructLiteral(
  1023. MatchStructFieldValue(MatchStructFieldDesignator(
  1024. ".", MatchDesignatedName("n")),
  1025. "=", MatchLiteral("4")),
  1026. MatchStructComma(), MatchStructEnd())),
  1027. MatchDeclarationEnd()),
  1028. MatchFileEnd()}));
  1029. }
  1030. TEST_F(ParseTreeTest, StructErrors) {
  1031. struct Testcase {
  1032. llvm::StringLiteral input;
  1033. ::testing::Matcher<const Diagnostic&> diag_matcher;
  1034. };
  1035. Testcase testcases[] = {
  1036. {"var x: {i32} = {};",
  1037. DiagnosticMessage("Expected `.field: type` or `.field = value`.")},
  1038. {"var x: {a} = {};",
  1039. DiagnosticMessage("Expected `.field: type` or `.field = value`.")},
  1040. {"var x: {a:} = {};",
  1041. DiagnosticMessage("Expected `.field: type` or `.field = value`.")},
  1042. {"var x: {a=} = {};",
  1043. DiagnosticMessage("Expected `.field: type` or `.field = value`.")},
  1044. {"var x: {.} = {};", DiagnosticMessage("Expected identifier after `.`.")},
  1045. {"var x: {.\"hello\" = 0, .y = 4} = {};",
  1046. DiagnosticMessage("Expected identifier after `.`.")},
  1047. {"var x: {.\"hello\": i32, .y: i32} = {};",
  1048. DiagnosticMessage("Expected identifier after `.`.")},
  1049. {"var x: {.a} = {};",
  1050. DiagnosticMessage("Expected `.field: type` or `.field = value`.")},
  1051. {"var x: {.a:} = {};", DiagnosticMessage("Expected expression.")},
  1052. {"var x: {.a=} = {};", DiagnosticMessage("Expected expression.")},
  1053. {"var x: {.a: i32, .b = 0} = {};",
  1054. DiagnosticMessage("Expected `.field: type`.")},
  1055. {"var x: {.a = 0, b: i32} = {};",
  1056. DiagnosticMessage("Expected `.field = value`.")},
  1057. {"var x: {,} = {};",
  1058. DiagnosticMessage("Expected `.field: type` or `.field = value`.")},
  1059. {"var x: {.a: i32,,} = {};",
  1060. DiagnosticMessage("Expected `.field: type`.")},
  1061. {"var x: {.a = 0,,} = {};",
  1062. DiagnosticMessage("Expected `.field = value`.")},
  1063. {"var x: {.a: i32 banana} = {.a = 0};",
  1064. DiagnosticMessage("Expected `,` or `}`.")},
  1065. {"var x: {.a: i32} = {.a = 0 banana};",
  1066. DiagnosticMessage("Expected `,` or `}`.")},
  1067. };
  1068. for (const Testcase& testcase : testcases) {
  1069. TokenizedBuffer tokens = GetTokenizedBuffer(testcase.input);
  1070. Testing::MockDiagnosticConsumer consumer;
  1071. EXPECT_CALL(consumer, HandleDiagnostic(testcase.diag_matcher));
  1072. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1073. EXPECT_TRUE(tree.has_errors());
  1074. }
  1075. }
  1076. auto GetAndDropLine(llvm::StringRef& s) -> std::string {
  1077. auto newline_offset = s.find_first_of('\n');
  1078. llvm::StringRef line = s.slice(0, newline_offset);
  1079. if (newline_offset != llvm::StringRef::npos) {
  1080. s = s.substr(newline_offset + 1);
  1081. } else {
  1082. s = "";
  1083. }
  1084. return line.str();
  1085. }
  1086. TEST_F(ParseTreeTest, Printing) {
  1087. TokenizedBuffer tokens = GetTokenizedBuffer("fn F();");
  1088. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1089. EXPECT_FALSE(tree.has_errors());
  1090. std::string print_storage;
  1091. llvm::raw_string_ostream print_stream(print_storage);
  1092. tree.Print(print_stream);
  1093. llvm::StringRef print = print_stream.str();
  1094. EXPECT_THAT(GetAndDropLine(print), StrEq("["));
  1095. EXPECT_THAT(GetAndDropLine(print),
  1096. StrEq("{node_index: 4, kind: 'FunctionDeclaration', text: 'fn', "
  1097. "subtree_size: 5, children: ["));
  1098. EXPECT_THAT(GetAndDropLine(print),
  1099. StrEq(" {node_index: 0, kind: 'DeclaredName', text: 'F'},"));
  1100. EXPECT_THAT(GetAndDropLine(print),
  1101. StrEq(" {node_index: 2, kind: 'ParameterList', text: '(', "
  1102. "subtree_size: 2, children: ["));
  1103. EXPECT_THAT(GetAndDropLine(print),
  1104. StrEq(" {node_index: 1, kind: 'ParameterListEnd', "
  1105. "text: ')'}]},"));
  1106. EXPECT_THAT(GetAndDropLine(print),
  1107. StrEq(" {node_index: 3, kind: 'DeclarationEnd', text: ';'}]},"));
  1108. EXPECT_THAT(GetAndDropLine(print),
  1109. StrEq("{node_index: 5, kind: 'FileEnd', text: ''},"));
  1110. EXPECT_THAT(GetAndDropLine(print), StrEq("]"));
  1111. EXPECT_TRUE(print.empty()) << print;
  1112. }
  1113. TEST_F(ParseTreeTest, PrintingAsYAML) {
  1114. TokenizedBuffer tokens = GetTokenizedBuffer("fn F();");
  1115. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1116. EXPECT_FALSE(tree.has_errors());
  1117. std::string print_output;
  1118. llvm::raw_string_ostream print_stream(print_output);
  1119. tree.Print(print_stream);
  1120. print_stream.flush();
  1121. EXPECT_THAT(
  1122. Yaml::Value::FromText(print_output),
  1123. ElementsAre(Yaml::SequenceValue{
  1124. Yaml::MappingValue{
  1125. {"node_index", "4"},
  1126. {"kind", "FunctionDeclaration"},
  1127. {"text", "fn"},
  1128. {"subtree_size", "5"},
  1129. {"children",
  1130. Yaml::SequenceValue{
  1131. Yaml::MappingValue{{"node_index", "0"},
  1132. {"kind", "DeclaredName"},
  1133. {"text", "F"}},
  1134. Yaml::MappingValue{{"node_index", "2"},
  1135. {"kind", "ParameterList"},
  1136. {"text", "("},
  1137. {"subtree_size", "2"},
  1138. {"children", //
  1139. Yaml::SequenceValue{Yaml::MappingValue{
  1140. {"node_index", "1"},
  1141. {"kind", "ParameterListEnd"},
  1142. {"text", ")"}}}}},
  1143. Yaml::MappingValue{{"node_index", "3"},
  1144. {"kind", "DeclarationEnd"},
  1145. {"text", ";"}}}}},
  1146. Yaml::MappingValue{{"node_index", "5"}, //
  1147. {"kind", "FileEnd"},
  1148. {"text", ""}}}));
  1149. }
  1150. TEST_F(ParseTreeTest, ParenMatchRegression) {
  1151. // A regression test that the search for the closing `)` doesn't end early on
  1152. // the closing `}` when it skips over the nested scope.
  1153. TokenizedBuffer tokens = GetTokenizedBuffer("var = (foo {})");
  1154. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1155. EXPECT_TRUE(tree.has_errors());
  1156. EXPECT_THAT(
  1157. tree, MatchParseTreeNodes(
  1158. {MatchVariableDeclaration(
  1159. HasError, MatchVariableInitializer(
  1160. "=", MatchParenExpression(
  1161. HasError, MatchNameReference("foo"),
  1162. MatchParenExpressionEnd()))),
  1163. MatchFileEnd()}));
  1164. }
  1165. TEST_F(ParseTreeTest, RecursionLimit) {
  1166. std::string code = "fn Foo() { return ";
  1167. code.append(10000, '(');
  1168. code.append(10000, ')');
  1169. code += "; }";
  1170. TokenizedBuffer tokens = GetTokenizedBuffer(code);
  1171. ASSERT_FALSE(tokens.has_errors());
  1172. Testing::MockDiagnosticConsumer consumer;
  1173. // Recursion might be exceeded multiple times due to quirks in parse tree
  1174. // handling; we only need to be sure it's hit at least once for test
  1175. // correctness.
  1176. EXPECT_CALL(
  1177. consumer,
  1178. HandleDiagnostic(DiagnosticMessage(llvm::formatv(
  1179. "Exceeded recursion limit ({0})", ParseTree::StackDepthLimit))))
  1180. .Times(AtLeast(1));
  1181. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1182. EXPECT_TRUE(tree.has_errors());
  1183. }
  1184. TEST_F(ParseTreeTest, ParsePostfixExpressionRegression) {
  1185. // Stack depth errors could cause ParsePostfixExpression to infinitely loop
  1186. // when calling children and those children error. Because of the fragility of
  1187. // stack depth, this tries a few different values.
  1188. for (int n = 0; n <= 10; ++n) {
  1189. std::string code = "var x: auto = ";
  1190. code.append(ParseTree::StackDepthLimit - n, '*');
  1191. code += "(z);";
  1192. TokenizedBuffer tokens = GetTokenizedBuffer(code);
  1193. ASSERT_FALSE(tokens.has_errors());
  1194. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1195. EXPECT_TRUE(tree.has_errors());
  1196. }
  1197. }
  1198. } // namespace
  1199. } // namespace Carbon::Testing