pattern_test.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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 "executable_semantics/ast/pattern.h"
  5. #include "executable_semantics/ast/expression.h"
  6. #include "executable_semantics/ast/paren_contents.h"
  7. #include "executable_semantics/common/arena.h"
  8. #include "gmock/gmock.h"
  9. #include "gtest/gtest.h"
  10. #include "llvm/Support/Casting.h"
  11. namespace Carbon {
  12. namespace {
  13. using llvm::cast;
  14. using llvm::isa;
  15. using testing::ElementsAre;
  16. using testing::IsEmpty;
  17. // Matches a TuplePattern::Field named `name` whose `pattern` is an
  18. // `AutoPattern`.
  19. MATCHER_P(AutoFieldNamed, name, "") {
  20. return arg.name == std::string(name) && isa<AutoPattern>(*arg.pattern);
  21. }
  22. static auto FakeSourceLoc(int line_num) -> SourceLocation {
  23. return SourceLocation("<test>", line_num);
  24. }
  25. TEST(PatternTest, EmptyAsPattern) {
  26. ParenContents<Pattern> contents = {.elements = {},
  27. .has_trailing_comma = false};
  28. Ptr<const Pattern> pattern =
  29. PatternFromParenContents(FakeSourceLoc(1), contents);
  30. EXPECT_EQ(pattern->SourceLoc(), FakeSourceLoc(1));
  31. ASSERT_TRUE(isa<TuplePattern>(*pattern));
  32. EXPECT_THAT(cast<TuplePattern>(*pattern).Fields(), IsEmpty());
  33. }
  34. TEST(PatternTest, EmptyAsTuplePattern) {
  35. ParenContents<Pattern> contents = {.elements = {},
  36. .has_trailing_comma = false};
  37. Ptr<const TuplePattern> tuple =
  38. TuplePatternFromParenContents(FakeSourceLoc(1), contents);
  39. EXPECT_EQ(tuple->SourceLoc(), FakeSourceLoc(1));
  40. EXPECT_THAT(tuple->Fields(), IsEmpty());
  41. }
  42. TEST(PatternTest, UnaryNoCommaAsPattern) {
  43. // Equivalent to a code fragment like
  44. // ```
  45. // (
  46. // auto
  47. // )
  48. // ```
  49. ParenContents<Pattern> contents = {
  50. .elements = {{.name = std::nullopt,
  51. .term = global_arena->New<AutoPattern>(FakeSourceLoc(2))}},
  52. .has_trailing_comma = false};
  53. Ptr<const Pattern> pattern =
  54. PatternFromParenContents(FakeSourceLoc(1), contents);
  55. EXPECT_EQ(pattern->SourceLoc(), FakeSourceLoc(2));
  56. ASSERT_TRUE(isa<AutoPattern>(*pattern));
  57. }
  58. TEST(PatternTest, UnaryNoCommaAsTuplePattern) {
  59. ParenContents<Pattern> contents = {
  60. .elements = {{.name = std::nullopt,
  61. .term = global_arena->New<AutoPattern>(FakeSourceLoc(2))}},
  62. .has_trailing_comma = false};
  63. Ptr<const TuplePattern> tuple =
  64. TuplePatternFromParenContents(FakeSourceLoc(1), contents);
  65. EXPECT_EQ(tuple->SourceLoc(), FakeSourceLoc(1));
  66. EXPECT_THAT(tuple->Fields(), ElementsAre(AutoFieldNamed("0")));
  67. }
  68. TEST(PatternTest, UnaryWithCommaAsPattern) {
  69. ParenContents<Pattern> contents = {
  70. .elements = {{.name = std::nullopt,
  71. .term = global_arena->New<AutoPattern>(FakeSourceLoc(2))}},
  72. .has_trailing_comma = true};
  73. Ptr<const Pattern> pattern =
  74. PatternFromParenContents(FakeSourceLoc(1), contents);
  75. EXPECT_EQ(pattern->SourceLoc(), FakeSourceLoc(1));
  76. ASSERT_TRUE(isa<TuplePattern>(*pattern));
  77. EXPECT_THAT(cast<TuplePattern>(*pattern).Fields(),
  78. ElementsAre(AutoFieldNamed("0")));
  79. }
  80. TEST(PatternTest, UnaryWithCommaAsTuplePattern) {
  81. ParenContents<Pattern> contents = {
  82. .elements = {{.name = std::nullopt,
  83. .term = global_arena->New<AutoPattern>(FakeSourceLoc(2))}},
  84. .has_trailing_comma = true};
  85. Ptr<const TuplePattern> tuple =
  86. TuplePatternFromParenContents(FakeSourceLoc(1), contents);
  87. EXPECT_EQ(tuple->SourceLoc(), FakeSourceLoc(1));
  88. EXPECT_THAT(tuple->Fields(), ElementsAre(AutoFieldNamed("0")));
  89. }
  90. TEST(PatternTest, BinaryAsPattern) {
  91. ParenContents<Pattern> contents = {
  92. .elements = {{.name = std::nullopt,
  93. .term = global_arena->New<AutoPattern>(FakeSourceLoc(2))},
  94. {.name = std::nullopt,
  95. .term = global_arena->New<AutoPattern>(FakeSourceLoc(2))}},
  96. .has_trailing_comma = true};
  97. Ptr<const Pattern> pattern =
  98. PatternFromParenContents(FakeSourceLoc(1), contents);
  99. EXPECT_EQ(pattern->SourceLoc(), FakeSourceLoc(1));
  100. ASSERT_TRUE(isa<TuplePattern>(*pattern));
  101. EXPECT_THAT(cast<TuplePattern>(*pattern).Fields(),
  102. ElementsAre(AutoFieldNamed("0"), AutoFieldNamed("1")));
  103. }
  104. TEST(PatternTest, BinaryAsTuplePattern) {
  105. ParenContents<Pattern> contents = {
  106. .elements = {{.name = std::nullopt,
  107. .term = global_arena->New<AutoPattern>(FakeSourceLoc(2))},
  108. {.name = std::nullopt,
  109. .term = global_arena->New<AutoPattern>(FakeSourceLoc(2))}},
  110. .has_trailing_comma = true};
  111. Ptr<const TuplePattern> tuple =
  112. TuplePatternFromParenContents(FakeSourceLoc(1), contents);
  113. EXPECT_EQ(tuple->SourceLoc(), FakeSourceLoc(1));
  114. EXPECT_THAT(tuple->Fields(),
  115. ElementsAre(AutoFieldNamed("0"), AutoFieldNamed("1")));
  116. }
  117. } // namespace
  118. } // namespace Carbon