semantics_ir_factory_test.cpp 5.2 KB

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