semantics_ir_factory_test.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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/semantics/semantics_ir_factory.h"
  5. #include <gmock/gmock.h>
  6. #include <gtest/gtest.h>
  7. #include "toolchain/diagnostics/mocks.h"
  8. #include "toolchain/lexer/tokenized_buffer.h"
  9. #include "toolchain/parser/parse_tree.h"
  10. #include "toolchain/semantics/semantics_ir_test_helpers.h"
  11. #include "toolchain/source/source_buffer.h"
  12. namespace Carbon::Testing {
  13. namespace {
  14. using ::testing::_;
  15. using ::testing::ElementsAre;
  16. using ::testing::Eq;
  17. using ::testing::IsEmpty;
  18. using ::testing::Optional;
  19. using ::testing::UnorderedElementsAre;
  20. class SemanticsIRFactoryTest : public ::testing::Test {
  21. protected:
  22. void Build(llvm::Twine t) {
  23. source_buffer.emplace(std::move(*SourceBuffer::CreateFromText(t)));
  24. tokenized_buffer = TokenizedBuffer::Lex(*source_buffer, consumer);
  25. EXPECT_FALSE(tokenized_buffer->has_errors());
  26. parse_tree = ParseTree::Parse(*tokenized_buffer, consumer);
  27. EXPECT_FALSE(parse_tree->has_errors());
  28. SemanticsIRForTest::set_semantics(SemanticsIRFactory::Build(*parse_tree));
  29. }
  30. ~SemanticsIRFactoryTest() override { SemanticsIRForTest::clear(); }
  31. void ExpectRootBlock(
  32. ::testing::Matcher<llvm::ArrayRef<Semantics::Declaration>> decls,
  33. ::testing::Matcher<llvm::StringMap<Semantics::Declaration>> name_lookup) {
  34. EXPECT_THAT(SemanticsIRForTest::semantics().root_block().nodes(), decls);
  35. EXPECT_THAT(SemanticsIRForTest::semantics().root_block().name_lookup(),
  36. name_lookup);
  37. }
  38. llvm::Optional<SourceBuffer> source_buffer;
  39. llvm::Optional<TokenizedBuffer> tokenized_buffer;
  40. llvm::Optional<ParseTree> parse_tree;
  41. MockDiagnosticConsumer consumer;
  42. };
  43. /*
  44. TEST_F(SemanticsIRFactoryTest, SimpleProgram) {
  45. EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
  46. Build(R"(// package FactoryTest api;
  47. fn Add(x: i32, y: i32) -> i32 {
  48. return x + y;
  49. }
  50. fn Main() -> i32 {
  51. var x: i32 = Add(3, 10);
  52. x *= 5;
  53. return x;
  54. }
  55. )");
  56. ExpectRootBlock(
  57. ElementsAre(
  58. Function(
  59. Eq("Add"),
  60. ElementsAre(PatternBinding(Eq("x"), Literal("i32")),
  61. PatternBinding(Eq("y"), Literal("i32"))),
  62. Optional(Literal("i32"))),
  63. Function(Eq("Main"), IsEmpty(), Optional(Literal("i32")))),
  64. UnorderedElementsAre(MappedNode("Add", FunctionName("Add")),
  65. MappedNode("Main", FunctionName("Main"))));
  66. }
  67. */
  68. TEST_F(SemanticsIRFactoryTest, Empty) {
  69. EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
  70. Build("");
  71. ExpectRootBlock(IsEmpty(), IsEmpty());
  72. }
  73. TEST_F(SemanticsIRFactoryTest, FunctionBasic) {
  74. EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
  75. Build("fn Foo() {}");
  76. ExpectRootBlock(ElementsAre(Function(Eq("Foo"), IsEmpty(), IsNone(),
  77. StatementBlock(IsEmpty(), IsEmpty()))),
  78. UnorderedElementsAre(MappedNode("Foo", FunctionName("Foo"))));
  79. }
  80. TEST_F(SemanticsIRFactoryTest, FunctionParams) {
  81. EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
  82. Build("fn Foo(x: i32, y: i64) {}");
  83. ExpectRootBlock(
  84. ElementsAre(Function(Eq("Foo"),
  85. ElementsAre(PatternBinding(Eq("x"), Literal("i32")),
  86. PatternBinding(Eq("y"), Literal("i64"))),
  87. IsNone(), StatementBlock(IsEmpty(), IsEmpty()))),
  88. UnorderedElementsAre(MappedNode("Foo", FunctionName("Foo"))));
  89. }
  90. TEST_F(SemanticsIRFactoryTest, FunctionReturnType) {
  91. EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
  92. Build("fn Foo() -> i32 {}");
  93. ExpectRootBlock(
  94. ElementsAre(Function(Eq("Foo"), IsEmpty(), Optional(Literal("i32")),
  95. StatementBlock(IsEmpty(), IsEmpty()))),
  96. UnorderedElementsAre(MappedNode("Foo", FunctionName("Foo"))));
  97. }
  98. TEST_F(SemanticsIRFactoryTest, FunctionDuplicate) {
  99. EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
  100. Build(R"(fn Foo() {}
  101. fn Foo() {}
  102. )");
  103. ExpectRootBlock(ElementsAre(FunctionName("Foo"), FunctionName("Foo")),
  104. UnorderedElementsAre(MappedNode("Foo", FunctionName("Foo"))));
  105. }
  106. TEST_F(SemanticsIRFactoryTest, FunctionOrder) {
  107. EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
  108. Build(R"(fn Foo() {}
  109. fn Bar() {}
  110. )");
  111. ExpectRootBlock(ElementsAre(FunctionName("Foo"), FunctionName("Bar")),
  112. UnorderedElementsAre(MappedNode("Bar", FunctionName("Bar")),
  113. MappedNode("Foo", FunctionName("Foo"))));
  114. }
  115. TEST_F(SemanticsIRFactoryTest, TrivialReturn) {
  116. EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
  117. Build(R"(fn Main() {
  118. return;
  119. }
  120. )");
  121. ExpectRootBlock(
  122. ElementsAre(
  123. Function(Eq("Main"), IsEmpty(), IsNone(),
  124. StatementBlock(ElementsAre(Return(IsNone())), IsEmpty()))),
  125. UnorderedElementsAre(MappedNode("Main", FunctionName("Main"))));
  126. }
  127. TEST_F(SemanticsIRFactoryTest, ReturnLiteral) {
  128. EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
  129. Build(R"(fn Main() {
  130. return 1;
  131. }
  132. )");
  133. ExpectRootBlock(
  134. ElementsAre(
  135. Function(Eq("Main"), IsEmpty(), IsNone(),
  136. StatementBlock(ElementsAre(Return(Optional(Literal("1")))),
  137. IsEmpty()))),
  138. UnorderedElementsAre(MappedNode("Main", FunctionName("Main"))));
  139. }
  140. TEST_F(SemanticsIRFactoryTest, ReturnArithmetic) {
  141. EXPECT_CALL(consumer, HandleDiagnostic(_)).Times(0);
  142. Build(R"(fn Main() {
  143. return 1 + 2;
  144. }
  145. )");
  146. ExpectRootBlock(
  147. ElementsAre(
  148. Function(Eq("Main"), IsEmpty(), IsNone(),
  149. StatementBlock(ElementsAre(Return(Optional(InfixOperator(
  150. Literal("1"), "+", Literal("2"))))),
  151. IsEmpty()))),
  152. UnorderedElementsAre(MappedNode("Main", FunctionName("Main"))));
  153. }
  154. } // namespace
  155. } // namespace Carbon::Testing