expression_test.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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/expression.h"
  5. #include <gmock/gmock.h>
  6. #include <gtest/gtest.h>
  7. #include <string>
  8. #include "executable_semantics/ast/paren_contents.h"
  9. #include "executable_semantics/common/arena.h"
  10. #include "llvm/Support/Casting.h"
  11. namespace Carbon {
  12. namespace {
  13. using llvm::cast;
  14. using testing::ElementsAre;
  15. using testing::IsEmpty;
  16. // Matches any `IntLiteral`.
  17. MATCHER(IntField, "") { return arg->kind() == ExpressionKind::IntLiteral; }
  18. static auto FakeSourceLoc(int line_num) -> SourceLocation {
  19. return SourceLocation("<test>", line_num);
  20. }
  21. class ExpressionTest : public ::testing::Test {
  22. protected:
  23. Arena arena;
  24. };
  25. TEST_F(ExpressionTest, EmptyAsExpression) {
  26. ParenContents<Expression> contents = {.elements = {},
  27. .has_trailing_comma = false};
  28. Nonnull<const Expression*> expression =
  29. ExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
  30. EXPECT_EQ(expression->source_loc(), FakeSourceLoc(1));
  31. ASSERT_EQ(expression->kind(), ExpressionKind::TupleLiteral);
  32. EXPECT_THAT(cast<TupleLiteral>(*expression).fields(), IsEmpty());
  33. }
  34. TEST_F(ExpressionTest, EmptyAsTuple) {
  35. ParenContents<Expression> contents = {.elements = {},
  36. .has_trailing_comma = false};
  37. Nonnull<const Expression*> tuple =
  38. TupleExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
  39. EXPECT_EQ(tuple->source_loc(), FakeSourceLoc(1));
  40. ASSERT_EQ(tuple->kind(), ExpressionKind::TupleLiteral);
  41. EXPECT_THAT(cast<TupleLiteral>(*tuple).fields(), IsEmpty());
  42. }
  43. TEST_F(ExpressionTest, UnaryNoCommaAsExpression) {
  44. // Equivalent to a code fragment like
  45. // ```
  46. // (
  47. // 42
  48. // )
  49. // ```
  50. ParenContents<Expression> contents = {
  51. .elements = {arena.New<IntLiteral>(FakeSourceLoc(2), 42)},
  52. .has_trailing_comma = false};
  53. Nonnull<const Expression*> expression =
  54. ExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
  55. EXPECT_EQ(expression->source_loc(), FakeSourceLoc(2));
  56. ASSERT_EQ(expression->kind(), ExpressionKind::IntLiteral);
  57. }
  58. TEST_F(ExpressionTest, UnaryNoCommaAsTuple) {
  59. ParenContents<Expression> contents = {
  60. .elements = {arena.New<IntLiteral>(FakeSourceLoc(2), 42)},
  61. .has_trailing_comma = false};
  62. Nonnull<const Expression*> tuple =
  63. TupleExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
  64. EXPECT_EQ(tuple->source_loc(), FakeSourceLoc(1));
  65. ASSERT_EQ(tuple->kind(), ExpressionKind::TupleLiteral);
  66. EXPECT_THAT(cast<TupleLiteral>(*tuple).fields(), ElementsAre(IntField()));
  67. }
  68. TEST_F(ExpressionTest, UnaryWithCommaAsExpression) {
  69. ParenContents<Expression> contents = {
  70. .elements = {arena.New<IntLiteral>(FakeSourceLoc(2), 42)},
  71. .has_trailing_comma = true};
  72. Nonnull<const Expression*> expression =
  73. ExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
  74. EXPECT_EQ(expression->source_loc(), FakeSourceLoc(1));
  75. ASSERT_EQ(expression->kind(), ExpressionKind::TupleLiteral);
  76. EXPECT_THAT(cast<TupleLiteral>(*expression).fields(),
  77. ElementsAre(IntField()));
  78. }
  79. TEST_F(ExpressionTest, UnaryWithCommaAsTuple) {
  80. ParenContents<Expression> contents = {
  81. .elements = {arena.New<IntLiteral>(FakeSourceLoc(2), 42)},
  82. .has_trailing_comma = true};
  83. Nonnull<const Expression*> tuple =
  84. TupleExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
  85. EXPECT_EQ(tuple->source_loc(), FakeSourceLoc(1));
  86. ASSERT_EQ(tuple->kind(), ExpressionKind::TupleLiteral);
  87. EXPECT_THAT(cast<TupleLiteral>(*tuple).fields(), ElementsAre(IntField()));
  88. }
  89. TEST_F(ExpressionTest, BinaryAsExpression) {
  90. ParenContents<Expression> contents = {
  91. .elements = {arena.New<IntLiteral>(FakeSourceLoc(2), 42),
  92. arena.New<IntLiteral>(FakeSourceLoc(3), 42)},
  93. .has_trailing_comma = true};
  94. Nonnull<const Expression*> expression =
  95. ExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
  96. EXPECT_EQ(expression->source_loc(), FakeSourceLoc(1));
  97. ASSERT_EQ(expression->kind(), ExpressionKind::TupleLiteral);
  98. EXPECT_THAT(cast<TupleLiteral>(*expression).fields(),
  99. ElementsAre(IntField(), IntField()));
  100. }
  101. TEST_F(ExpressionTest, BinaryAsTuple) {
  102. ParenContents<Expression> contents = {
  103. .elements = {arena.New<IntLiteral>(FakeSourceLoc(2), 42),
  104. arena.New<IntLiteral>(FakeSourceLoc(3), 42)},
  105. .has_trailing_comma = true};
  106. Nonnull<const Expression*> tuple =
  107. TupleExpressionFromParenContents(&arena, FakeSourceLoc(1), contents);
  108. EXPECT_EQ(tuple->source_loc(), FakeSourceLoc(1));
  109. ASSERT_EQ(tuple->kind(), ExpressionKind::TupleLiteral);
  110. EXPECT_THAT(cast<TupleLiteral>(*tuple).fields(),
  111. ElementsAre(IntField(), IntField()));
  112. }
  113. } // namespace
  114. } // namespace Carbon