parse_tree_test.cpp 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360
  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. // TODO: 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, FunctionDefinitionWithIdentifierInStatements) {
  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. // TODO: 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. // TODO: 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. IsDiagnosticMessage("Expected `.field: type` or `.field = value`.")},
  1038. {"var x: {a} = {};",
  1039. IsDiagnosticMessage("Expected `.field: type` or `.field = value`.")},
  1040. {"var x: {a:} = {};",
  1041. IsDiagnosticMessage("Expected `.field: type` or `.field = value`.")},
  1042. {"var x: {a=} = {};",
  1043. IsDiagnosticMessage("Expected `.field: type` or `.field = value`.")},
  1044. {"var x: {.} = {};",
  1045. IsDiagnosticMessage("Expected identifier after `.`.")},
  1046. {"var x: {.\"hello\" = 0, .y = 4} = {};",
  1047. IsDiagnosticMessage("Expected identifier after `.`.")},
  1048. {"var x: {.\"hello\": i32, .y: i32} = {};",
  1049. IsDiagnosticMessage("Expected identifier after `.`.")},
  1050. {"var x: {.a} = {};",
  1051. IsDiagnosticMessage("Expected `.field: type` or `.field = value`.")},
  1052. {"var x: {.a:} = {};", IsDiagnosticMessage("Expected expression.")},
  1053. {"var x: {.a=} = {};", IsDiagnosticMessage("Expected expression.")},
  1054. {"var x: {.a: i32, .b = 0} = {};",
  1055. IsDiagnosticMessage("Expected `.field: type`.")},
  1056. {"var x: {.a = 0, b: i32} = {};",
  1057. IsDiagnosticMessage("Expected `.field = value`.")},
  1058. {"var x: {,} = {};",
  1059. IsDiagnosticMessage("Expected `.field: type` or `.field = value`.")},
  1060. {"var x: {.a: i32,,} = {};",
  1061. IsDiagnosticMessage("Expected `.field: type`.")},
  1062. {"var x: {.a = 0,,} = {};",
  1063. IsDiagnosticMessage("Expected `.field = value`.")},
  1064. {"var x: {.a: i32 banana} = {.a = 0};",
  1065. IsDiagnosticMessage("Expected `,` or `}`.")},
  1066. {"var x: {.a: i32} = {.a = 0 banana};",
  1067. IsDiagnosticMessage("Expected `,` or `}`.")},
  1068. };
  1069. for (const Testcase& testcase : testcases) {
  1070. TokenizedBuffer tokens = GetTokenizedBuffer(testcase.input);
  1071. Testing::MockDiagnosticConsumer consumer;
  1072. EXPECT_CALL(consumer, HandleDiagnostic(testcase.diag_matcher));
  1073. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1074. EXPECT_TRUE(tree.has_errors());
  1075. }
  1076. }
  1077. auto GetAndDropLine(llvm::StringRef& s) -> std::string {
  1078. auto newline_offset = s.find_first_of('\n');
  1079. llvm::StringRef line = s.slice(0, newline_offset);
  1080. if (newline_offset != llvm::StringRef::npos) {
  1081. s = s.substr(newline_offset + 1);
  1082. } else {
  1083. s = "";
  1084. }
  1085. return line.str();
  1086. }
  1087. TEST_F(ParseTreeTest, Printing) {
  1088. TokenizedBuffer tokens = GetTokenizedBuffer("fn F();");
  1089. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1090. EXPECT_FALSE(tree.has_errors());
  1091. std::string print_storage;
  1092. llvm::raw_string_ostream print_stream(print_storage);
  1093. tree.Print(print_stream);
  1094. llvm::StringRef print = print_stream.str();
  1095. EXPECT_THAT(GetAndDropLine(print), StrEq("["));
  1096. EXPECT_THAT(GetAndDropLine(print),
  1097. StrEq("{node_index: 4, kind: 'FunctionDeclaration', text: 'fn', "
  1098. "subtree_size: 5, children: ["));
  1099. EXPECT_THAT(GetAndDropLine(print),
  1100. StrEq(" {node_index: 0, kind: 'DeclaredName', text: 'F'},"));
  1101. EXPECT_THAT(GetAndDropLine(print),
  1102. StrEq(" {node_index: 2, kind: 'ParameterList', text: '(', "
  1103. "subtree_size: 2, children: ["));
  1104. EXPECT_THAT(GetAndDropLine(print),
  1105. StrEq(" {node_index: 1, kind: 'ParameterListEnd', "
  1106. "text: ')'}]},"));
  1107. EXPECT_THAT(GetAndDropLine(print),
  1108. StrEq(" {node_index: 3, kind: 'DeclarationEnd', text: ';'}]},"));
  1109. EXPECT_THAT(GetAndDropLine(print),
  1110. StrEq("{node_index: 5, kind: 'FileEnd', text: ''},"));
  1111. EXPECT_THAT(GetAndDropLine(print), StrEq("]"));
  1112. EXPECT_TRUE(print.empty()) << print;
  1113. }
  1114. TEST_F(ParseTreeTest, PrintingAsYAML) {
  1115. TokenizedBuffer tokens = GetTokenizedBuffer("fn F();");
  1116. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1117. EXPECT_FALSE(tree.has_errors());
  1118. std::string print_output;
  1119. llvm::raw_string_ostream print_stream(print_output);
  1120. tree.Print(print_stream);
  1121. print_stream.flush();
  1122. EXPECT_THAT(
  1123. Yaml::Value::FromText(print_output),
  1124. ElementsAre(Yaml::SequenceValue{
  1125. Yaml::MappingValue{
  1126. {"node_index", "4"},
  1127. {"kind", "FunctionDeclaration"},
  1128. {"text", "fn"},
  1129. {"subtree_size", "5"},
  1130. {"children",
  1131. Yaml::SequenceValue{
  1132. Yaml::MappingValue{{"node_index", "0"},
  1133. {"kind", "DeclaredName"},
  1134. {"text", "F"}},
  1135. Yaml::MappingValue{{"node_index", "2"},
  1136. {"kind", "ParameterList"},
  1137. {"text", "("},
  1138. {"subtree_size", "2"},
  1139. {"children", //
  1140. Yaml::SequenceValue{Yaml::MappingValue{
  1141. {"node_index", "1"},
  1142. {"kind", "ParameterListEnd"},
  1143. {"text", ")"}}}}},
  1144. Yaml::MappingValue{{"node_index", "3"},
  1145. {"kind", "DeclarationEnd"},
  1146. {"text", ";"}}}}},
  1147. Yaml::MappingValue{{"node_index", "5"}, //
  1148. {"kind", "FileEnd"},
  1149. {"text", ""}}}));
  1150. }
  1151. TEST_F(ParseTreeTest, ParenMatchRegression) {
  1152. // A regression test that the search for the closing `)` doesn't end early on
  1153. // the closing `}` when it skips over the nested scope.
  1154. TokenizedBuffer tokens = GetTokenizedBuffer("var = (foo {})");
  1155. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1156. EXPECT_TRUE(tree.has_errors());
  1157. EXPECT_THAT(
  1158. tree, MatchParseTreeNodes(
  1159. {MatchVariableDeclaration(
  1160. HasError, MatchVariableInitializer(
  1161. "=", MatchParenExpression(
  1162. HasError, MatchNameReference("foo"),
  1163. MatchParenExpressionEnd()))),
  1164. MatchFileEnd()}));
  1165. }
  1166. TEST_F(ParseTreeTest, RecursionLimit) {
  1167. std::string code = "fn Foo() { return ";
  1168. code.append(10000, '(');
  1169. code.append(10000, ')');
  1170. code += "; }";
  1171. TokenizedBuffer tokens = GetTokenizedBuffer(code);
  1172. ASSERT_FALSE(tokens.has_errors());
  1173. Testing::MockDiagnosticConsumer consumer;
  1174. // Recursion might be exceeded multiple times due to quirks in parse tree
  1175. // handling; we only need to be sure it's hit at least once for test
  1176. // correctness.
  1177. EXPECT_CALL(consumer, HandleDiagnostic(IsDiagnosticMessage(
  1178. llvm::formatv("Exceeded recursion limit ({0})",
  1179. ParseTree::StackDepthLimit)
  1180. .str())))
  1181. .Times(AtLeast(1));
  1182. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1183. EXPECT_TRUE(tree.has_errors());
  1184. }
  1185. TEST_F(ParseTreeTest, ParsePostfixExpressionRegression) {
  1186. // Stack depth errors could cause ParsePostfixExpression to infinitely loop
  1187. // when calling children and those children error. Because of the fragility of
  1188. // stack depth, this tries a few different values.
  1189. for (int n = 0; n <= 10; ++n) {
  1190. std::string code = "var x: auto = ";
  1191. code.append(ParseTree::StackDepthLimit - n, '*');
  1192. code += "(z);";
  1193. TokenizedBuffer tokens = GetTokenizedBuffer(code);
  1194. ASSERT_FALSE(tokens.has_errors());
  1195. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1196. EXPECT_TRUE(tree.has_errors());
  1197. }
  1198. }
  1199. TEST_F(ParseTreeTest, Package) {
  1200. TokenizedBuffer tokens = GetTokenizedBuffer(R"(
  1201. package Geometry api;
  1202. package Geometry impl;
  1203. package Geometry library "Shapes" api;
  1204. package Geometry library "Shapes" impl;
  1205. )");
  1206. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1207. EXPECT_THAT(tree,
  1208. MatchParseTreeNodes(
  1209. {MatchPackageDirective(MatchDeclaredName("Geometry"),
  1210. MatchPackageApi(), MatchPackageEnd()),
  1211. MatchPackageDirective(MatchDeclaredName("Geometry"),
  1212. MatchPackageImpl(), MatchPackageEnd()),
  1213. MatchPackageDirective(
  1214. MatchDeclaredName("Geometry"),
  1215. MatchPackageLibrary(MatchLiteral("\"Shapes\"")),
  1216. MatchPackageApi(), MatchPackageEnd()),
  1217. MatchPackageDirective(
  1218. MatchDeclaredName("Geometry"),
  1219. MatchPackageLibrary(MatchLiteral("\"Shapes\"")),
  1220. MatchPackageImpl(), MatchPackageEnd()),
  1221. MatchFileEnd()}));
  1222. }
  1223. TEST_F(ParseTreeTest, PackageErrors) {
  1224. struct TestCase {
  1225. llvm::StringLiteral input;
  1226. ::testing::Matcher<const Diagnostic&> diag_matcher;
  1227. };
  1228. TestCase testcases[] = {
  1229. {"package;", IsDiagnosticMessage("Expected identifier after `package`.")},
  1230. {"package fn;",
  1231. IsDiagnosticMessage("Expected identifier after `package`.")},
  1232. {"package library \"Shapes\" api;",
  1233. IsDiagnosticMessage("Expected identifier after `package`.")},
  1234. {"package Geometry library Shapes api;",
  1235. IsDiagnosticMessage(
  1236. "Expected a string literal to specify the library name.")},
  1237. {"package Geometry \"Shapes\" api;",
  1238. IsDiagnosticMessage("Missing `library` keyword.")},
  1239. {"package Geometry api",
  1240. IsDiagnosticMessage("Expected `;` to end package directive.")},
  1241. {"package Geometry;", IsDiagnosticMessage("Expected a `api` or `impl`.")},
  1242. {R"(package Foo library "bar" "baz";)",
  1243. IsDiagnosticMessage("Expected a `api` or `impl`.")}};
  1244. for (const TestCase& testcase : testcases) {
  1245. TokenizedBuffer tokens = GetTokenizedBuffer(testcase.input);
  1246. Testing::MockDiagnosticConsumer consumer;
  1247. EXPECT_CALL(consumer, HandleDiagnostic(testcase.diag_matcher));
  1248. ParseTree tree = ParseTree::Parse(tokens, consumer);
  1249. EXPECT_TRUE(tree.has_errors());
  1250. }
  1251. }
  1252. } // namespace
  1253. } // namespace Carbon::Testing