name_scope_test.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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/sem_ir/name_scope.h"
  5. #include <gmock/gmock.h>
  6. #include <gtest/gtest.h>
  7. namespace Carbon::SemIR {
  8. namespace {
  9. using ::testing::ElementsAre;
  10. using ::testing::Field;
  11. using ::testing::Pair;
  12. MATCHER_P(NameScopeEntryEquals, entry, "") {
  13. return ExplainMatchResult(
  14. AllOf(Field("name_id", &NameScope::Entry::name_id, entry.name_id),
  15. Field("inst_id", &NameScope::Entry::inst_id, entry.inst_id),
  16. Field("access_kind", &NameScope::Entry::access_kind,
  17. entry.access_kind)),
  18. arg, result_listener);
  19. }
  20. TEST(NameScope, Empty) {
  21. int id = 0;
  22. InstId scope_inst_id(++id);
  23. NameId scope_name_id(++id);
  24. NameScopeId parent_scope_id(++id);
  25. NameScope name_scope(scope_inst_id, scope_name_id, parent_scope_id);
  26. EXPECT_THAT(name_scope.entries(), ElementsAre());
  27. EXPECT_THAT(name_scope.extended_scopes(), ElementsAre());
  28. EXPECT_EQ(name_scope.inst_id(), scope_inst_id);
  29. EXPECT_EQ(name_scope.name_id(), scope_name_id);
  30. EXPECT_EQ(name_scope.parent_scope_id(), parent_scope_id);
  31. EXPECT_FALSE(name_scope.has_error());
  32. EXPECT_FALSE(name_scope.is_closed_import());
  33. EXPECT_FALSE(name_scope.is_imported_package());
  34. EXPECT_THAT(name_scope.import_ir_scopes(), ElementsAre());
  35. }
  36. TEST(NameScope, Lookup) {
  37. int id = 0;
  38. InstId scope_inst_id(++id);
  39. NameId scope_name_id(++id);
  40. NameScopeId parent_scope_id(++id);
  41. NameScope name_scope(scope_inst_id, scope_name_id, parent_scope_id);
  42. NameScope::Entry entry1 = {.name_id = NameId(++id),
  43. .inst_id = InstId(++id),
  44. .access_kind = AccessKind::Public};
  45. name_scope.AddRequired(entry1);
  46. NameScope::Entry entry2 = {.name_id = NameId(++id),
  47. .inst_id = InstId(++id),
  48. .access_kind = AccessKind::Protected};
  49. name_scope.AddRequired(entry2);
  50. NameScope::Entry entry3 = {.name_id = NameId(++id),
  51. .inst_id = InstId(++id),
  52. .access_kind = AccessKind::Private};
  53. name_scope.AddRequired(entry3);
  54. auto lookup = name_scope.Lookup(entry1.name_id);
  55. ASSERT_NE(lookup, std::nullopt);
  56. EXPECT_THAT(static_cast<NameScope&>(name_scope).GetEntry(*lookup),
  57. NameScopeEntryEquals(entry1));
  58. EXPECT_THAT(static_cast<const NameScope&>(name_scope).GetEntry(*lookup),
  59. NameScopeEntryEquals(entry1));
  60. lookup = name_scope.Lookup(entry2.name_id);
  61. ASSERT_NE(lookup, std::nullopt);
  62. EXPECT_THAT(name_scope.GetEntry(*lookup), NameScopeEntryEquals(entry2));
  63. lookup = name_scope.Lookup(entry3.name_id);
  64. ASSERT_NE(lookup, std::nullopt);
  65. EXPECT_THAT(name_scope.GetEntry(*lookup), NameScopeEntryEquals(entry3));
  66. NameId unknown_name_id(++id);
  67. lookup = name_scope.Lookup(unknown_name_id);
  68. EXPECT_EQ(lookup, std::nullopt);
  69. }
  70. TEST(NameScope, LookupOrAdd) {
  71. int id = 0;
  72. InstId scope_inst_id(++id);
  73. NameId scope_name_id(++id);
  74. NameScopeId parent_scope_id(++id);
  75. NameScope name_scope(scope_inst_id, scope_name_id, parent_scope_id);
  76. NameScope::Entry entry1 = {.name_id = NameId(++id),
  77. .inst_id = InstId(++id),
  78. .access_kind = AccessKind::Public};
  79. {
  80. auto [added, entry_id] = name_scope.LookupOrAdd(
  81. entry1.name_id, entry1.inst_id, entry1.access_kind);
  82. EXPECT_TRUE(added);
  83. EXPECT_THAT(name_scope.GetEntry(entry_id), NameScopeEntryEquals(entry1));
  84. }
  85. NameScope::Entry entry2 = {.name_id = NameId(++id),
  86. .inst_id = InstId(++id),
  87. .access_kind = AccessKind::Protected};
  88. {
  89. auto [added, entry_id] = name_scope.LookupOrAdd(
  90. entry2.name_id, entry2.inst_id, entry2.access_kind);
  91. EXPECT_TRUE(added);
  92. EXPECT_THAT(name_scope.GetEntry(entry_id), NameScopeEntryEquals(entry2));
  93. }
  94. NameScope::Entry entry3 = {.name_id = NameId(++id),
  95. .inst_id = InstId(++id),
  96. .access_kind = AccessKind::Private};
  97. {
  98. auto [added, entry_id] = name_scope.LookupOrAdd(
  99. entry3.name_id, entry3.inst_id, entry3.access_kind);
  100. EXPECT_TRUE(added);
  101. EXPECT_THAT(name_scope.GetEntry(entry_id), NameScopeEntryEquals(entry3));
  102. }
  103. {
  104. auto [added, entry_id] = name_scope.LookupOrAdd(
  105. entry1.name_id, entry1.inst_id, entry1.access_kind);
  106. EXPECT_FALSE(added);
  107. EXPECT_THAT(name_scope.GetEntry(entry_id), NameScopeEntryEquals(entry1));
  108. }
  109. {
  110. auto [added, entry_id] = name_scope.LookupOrAdd(
  111. entry2.name_id, entry2.inst_id, entry2.access_kind);
  112. EXPECT_FALSE(added);
  113. EXPECT_THAT(name_scope.GetEntry(entry_id), NameScopeEntryEquals(entry2));
  114. }
  115. {
  116. auto [added, entry_id] = name_scope.LookupOrAdd(
  117. entry3.name_id, entry3.inst_id, entry3.access_kind);
  118. EXPECT_FALSE(added);
  119. EXPECT_THAT(name_scope.GetEntry(entry_id), NameScopeEntryEquals(entry3));
  120. }
  121. }
  122. TEST(NameScope, ExtendedScopes) {
  123. int id = 0;
  124. InstId scope_inst_id(++id);
  125. NameId scope_name_id(++id);
  126. NameScopeId parent_scope_id = NameScopeId::Package;
  127. NameScope name_scope(scope_inst_id, scope_name_id, parent_scope_id);
  128. EXPECT_THAT(name_scope.extended_scopes(), ElementsAre());
  129. InstId extended_scope1(++id);
  130. name_scope.AddExtendedScope(extended_scope1);
  131. EXPECT_THAT(name_scope.extended_scopes(), ElementsAre(extended_scope1));
  132. InstId extended_scope2(++id);
  133. name_scope.AddExtendedScope(extended_scope2);
  134. EXPECT_THAT(name_scope.extended_scopes(),
  135. ElementsAre(extended_scope1, extended_scope2));
  136. }
  137. TEST(NameScope, HasError) {
  138. int id = 0;
  139. InstId scope_inst_id(++id);
  140. NameId scope_name_id(++id);
  141. NameScopeId parent_scope_id(++id);
  142. NameScope name_scope(scope_inst_id, scope_name_id, parent_scope_id);
  143. EXPECT_FALSE(name_scope.has_error());
  144. name_scope.set_has_error();
  145. EXPECT_TRUE(name_scope.has_error());
  146. name_scope.set_has_error();
  147. EXPECT_TRUE(name_scope.has_error());
  148. }
  149. TEST(NameScope, IsClosedImport) {
  150. int id = 0;
  151. InstId scope_inst_id(++id);
  152. NameId scope_name_id(++id);
  153. NameScopeId parent_scope_id(++id);
  154. NameScope name_scope(scope_inst_id, scope_name_id, parent_scope_id);
  155. EXPECT_FALSE(name_scope.is_closed_import());
  156. name_scope.set_is_closed_import(true);
  157. EXPECT_TRUE(name_scope.is_closed_import());
  158. name_scope.set_is_closed_import(false);
  159. EXPECT_FALSE(name_scope.is_closed_import());
  160. }
  161. TEST(NameScope, IsImportedPackageParentNonPackageScope) {
  162. int id = 0;
  163. InstId scope_inst_id(++id);
  164. NameId scope_name_id(++id);
  165. NameScopeId parent_scope_id(++id);
  166. NameScope name_scope(scope_inst_id, scope_name_id, parent_scope_id);
  167. EXPECT_FALSE(name_scope.is_imported_package());
  168. name_scope.set_is_closed_import(true);
  169. EXPECT_FALSE(name_scope.is_imported_package());
  170. name_scope.set_is_closed_import(false);
  171. EXPECT_FALSE(name_scope.is_imported_package());
  172. }
  173. TEST(NameScope, IsImportedPackageParentPackageScope) {
  174. int id = 0;
  175. InstId scope_inst_id(++id);
  176. NameId scope_name_id(++id);
  177. NameScopeId parent_scope_id = NameScopeId::Package;
  178. NameScope name_scope(scope_inst_id, scope_name_id, parent_scope_id);
  179. EXPECT_FALSE(name_scope.is_imported_package());
  180. name_scope.set_is_closed_import(true);
  181. EXPECT_TRUE(name_scope.is_imported_package());
  182. name_scope.set_is_closed_import(false);
  183. EXPECT_FALSE(name_scope.is_imported_package());
  184. }
  185. TEST(NameScope, ImportIRScopes) {
  186. int id = 0;
  187. InstId scope_inst_id(++id);
  188. NameId scope_name_id(++id);
  189. NameScopeId parent_scope_id = NameScopeId::Package;
  190. NameScope name_scope(scope_inst_id, scope_name_id, parent_scope_id);
  191. EXPECT_THAT(name_scope.import_ir_scopes(), ElementsAre());
  192. ImportIRId import_ir_id1(++id);
  193. NameScopeId import_name_scope_id1(++id);
  194. name_scope.AddImportIRScope({import_ir_id1, import_name_scope_id1});
  195. EXPECT_THAT(name_scope.import_ir_scopes(),
  196. ElementsAre(Pair(import_ir_id1, import_name_scope_id1)));
  197. ImportIRId import_ir_id2(++id);
  198. NameScopeId import_name_scope_id2(++id);
  199. name_scope.AddImportIRScope({import_ir_id2, import_name_scope_id2});
  200. EXPECT_THAT(name_scope.import_ir_scopes(),
  201. ElementsAre(Pair(import_ir_id1, import_name_scope_id1),
  202. Pair(import_ir_id2, import_name_scope_id2)));
  203. }
  204. } // namespace
  205. } // namespace Carbon::SemIR