rubydex 0.1.0.beta11 → 0.1.0.beta13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +23 -23
  3. data/README.md +125 -125
  4. data/THIRD_PARTY_LICENSES.html +2018 -945
  5. data/exe/rdx +47 -47
  6. data/ext/rubydex/declaration.c +453 -388
  7. data/ext/rubydex/declaration.h +23 -23
  8. data/ext/rubydex/definition.c +284 -197
  9. data/ext/rubydex/definition.h +28 -28
  10. data/ext/rubydex/diagnostic.c +6 -6
  11. data/ext/rubydex/diagnostic.h +11 -11
  12. data/ext/rubydex/document.c +97 -98
  13. data/ext/rubydex/document.h +10 -10
  14. data/ext/rubydex/extconf.rb +146 -127
  15. data/ext/rubydex/graph.c +701 -512
  16. data/ext/rubydex/graph.h +10 -10
  17. data/ext/rubydex/handle.h +44 -44
  18. data/ext/rubydex/location.c +22 -22
  19. data/ext/rubydex/location.h +15 -15
  20. data/ext/rubydex/reference.c +123 -104
  21. data/ext/rubydex/reference.h +15 -16
  22. data/ext/rubydex/rubydex.c +22 -22
  23. data/ext/rubydex/utils.c +108 -86
  24. data/ext/rubydex/utils.h +34 -28
  25. data/lib/rubydex/comment.rb +17 -17
  26. data/lib/rubydex/declaration.rb +11 -0
  27. data/lib/rubydex/diagnostic.rb +21 -21
  28. data/lib/rubydex/failures.rb +15 -15
  29. data/lib/rubydex/graph.rb +98 -92
  30. data/lib/rubydex/keyword.rb +17 -0
  31. data/lib/rubydex/keyword_parameter.rb +13 -0
  32. data/lib/rubydex/location.rb +90 -90
  33. data/lib/rubydex/mixin.rb +22 -0
  34. data/lib/rubydex/version.rb +5 -5
  35. data/lib/rubydex.rb +24 -20
  36. data/rbi/rubydex.rbi +425 -310
  37. data/rust/Cargo.lock +1851 -1851
  38. data/rust/Cargo.toml +29 -29
  39. data/rust/about.toml +10 -10
  40. data/rust/{about.hbs → about_templates/about.hbs} +81 -78
  41. data/rust/about_templates/mingw_licenses.hbs +1071 -0
  42. data/rust/rubydex/Cargo.toml +42 -42
  43. data/rust/rubydex/src/compile_assertions.rs +13 -13
  44. data/rust/rubydex/src/diagnostic.rs +110 -109
  45. data/rust/rubydex/src/errors.rs +28 -28
  46. data/rust/rubydex/src/indexing/local_graph.rs +224 -224
  47. data/rust/rubydex/src/indexing/rbs_indexer.rs +1551 -1554
  48. data/rust/rubydex/src/indexing/ruby_indexer.rs +2329 -6753
  49. data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +4962 -0
  50. data/rust/rubydex/src/indexing.rs +210 -210
  51. data/rust/rubydex/src/integrity.rs +279 -278
  52. data/rust/rubydex/src/job_queue.rs +199 -205
  53. data/rust/rubydex/src/lib.rs +17 -17
  54. data/rust/rubydex/src/listing.rs +371 -272
  55. data/rust/rubydex/src/main.rs +160 -160
  56. data/rust/rubydex/src/model/built_in.rs +83 -0
  57. data/rust/rubydex/src/model/comment.rs +24 -24
  58. data/rust/rubydex/src/model/declaration.rs +679 -588
  59. data/rust/rubydex/src/model/definitions.rs +1682 -1602
  60. data/rust/rubydex/src/model/document.rs +222 -252
  61. data/rust/rubydex/src/model/encoding.rs +22 -22
  62. data/rust/rubydex/src/model/graph.rs +3782 -3556
  63. data/rust/rubydex/src/model/id.rs +110 -110
  64. data/rust/rubydex/src/model/identity_maps.rs +58 -58
  65. data/rust/rubydex/src/model/ids.rs +60 -38
  66. data/rust/rubydex/src/model/keywords.rs +256 -256
  67. data/rust/rubydex/src/model/name.rs +298 -298
  68. data/rust/rubydex/src/model/references.rs +111 -111
  69. data/rust/rubydex/src/model/string_ref.rs +50 -50
  70. data/rust/rubydex/src/model/visibility.rs +41 -41
  71. data/rust/rubydex/src/model.rs +15 -14
  72. data/rust/rubydex/src/offset.rs +147 -147
  73. data/rust/rubydex/src/position.rs +6 -6
  74. data/rust/rubydex/src/query.rs +1841 -1700
  75. data/rust/rubydex/src/resolution.rs +1852 -5895
  76. data/rust/rubydex/src/resolution_tests.rs +4701 -0
  77. data/rust/rubydex/src/stats/memory.rs +71 -71
  78. data/rust/rubydex/src/stats/orphan_report.rs +264 -263
  79. data/rust/rubydex/src/stats/timer.rs +127 -127
  80. data/rust/rubydex/src/stats.rs +11 -11
  81. data/rust/rubydex/src/test_utils/context.rs +226 -226
  82. data/rust/rubydex/src/test_utils/graph_test.rs +730 -679
  83. data/rust/rubydex/src/test_utils/local_graph_test.rs +602 -602
  84. data/rust/rubydex/src/test_utils.rs +52 -52
  85. data/rust/rubydex/src/visualization/dot.rs +192 -176
  86. data/rust/rubydex/src/visualization.rs +6 -6
  87. data/rust/rubydex/tests/cli.rs +185 -167
  88. data/rust/rubydex-mcp/Cargo.toml +28 -28
  89. data/rust/rubydex-mcp/src/main.rs +48 -48
  90. data/rust/rubydex-mcp/src/server.rs +1145 -1145
  91. data/rust/rubydex-mcp/src/tools.rs +49 -49
  92. data/rust/rubydex-mcp/tests/mcp.rs +302 -302
  93. data/rust/rubydex-sys/Cargo.toml +20 -20
  94. data/rust/rubydex-sys/build.rs +14 -14
  95. data/rust/rubydex-sys/cbindgen.toml +12 -12
  96. data/rust/rubydex-sys/src/declaration_api.rs +485 -469
  97. data/rust/rubydex-sys/src/definition_api.rs +443 -352
  98. data/rust/rubydex-sys/src/diagnostic_api.rs +99 -99
  99. data/rust/rubydex-sys/src/document_api.rs +85 -54
  100. data/rust/rubydex-sys/src/graph_api.rs +1017 -700
  101. data/rust/rubydex-sys/src/lib.rs +79 -9
  102. data/rust/rubydex-sys/src/location_api.rs +79 -79
  103. data/rust/rubydex-sys/src/name_api.rs +187 -135
  104. data/rust/rubydex-sys/src/reference_api.rs +267 -195
  105. data/rust/rubydex-sys/src/utils.rs +70 -70
  106. data/rust/rustfmt.toml +2 -2
  107. metadata +16 -9
  108. data/lib/rubydex/librubydex_sys.so +0 -0
@@ -1,298 +1,298 @@
1
- use std::fmt::Display;
2
-
3
- use crate::{
4
- assert_mem_size,
5
- model::ids::{DeclarationId, NameId, StringId},
6
- };
7
-
8
- #[derive(Debug, Clone, Copy, PartialEq, Eq)]
9
- pub enum ParentScope {
10
- /// There's no parent scope in this reference (e.g.: `Foo`)
11
- None,
12
- /// There's an empty parent scope in this reference (e.g.: `::Foo`)
13
- TopLevel,
14
- /// There's a parent scope in this reference (e.g.: `Foo::Bar`)
15
- Some(NameId),
16
- /// Parent scope representing the class attached to a singleton class context
17
- ///
18
- /// `Foo::<Foo>::<<Foo>>`
19
- /// ^ Attached for <Foo>
20
- /// ^ Attached for <<Foo>>
21
- Attached(NameId),
22
- }
23
- assert_mem_size!(ParentScope, 16);
24
-
25
- impl ParentScope {
26
- pub fn map_or<F, T>(&self, default: T, f: F) -> T
27
- where
28
- F: FnOnce(&NameId) -> T,
29
- {
30
- match self {
31
- ParentScope::Some(id) | ParentScope::Attached(id) => f(id),
32
- _ => default,
33
- }
34
- }
35
-
36
- #[must_use]
37
- pub fn as_ref(&self) -> Option<&NameId> {
38
- match self {
39
- ParentScope::Some(id) | ParentScope::Attached(id) => Some(id),
40
- _ => None,
41
- }
42
- }
43
-
44
- #[must_use]
45
- pub fn is_none(&self) -> bool {
46
- matches!(self, ParentScope::None)
47
- }
48
-
49
- #[must_use]
50
- pub fn is_top_level(&self) -> bool {
51
- matches!(self, ParentScope::TopLevel)
52
- }
53
-
54
- /// # Panics
55
- ///
56
- /// Panics if the `ParentScope` is None or `TopLevel`
57
- #[must_use]
58
- pub fn expect(&self, message: &str) -> NameId {
59
- match self {
60
- ParentScope::Some(id) | ParentScope::Attached(id) => *id,
61
- _ => panic!("{}", message),
62
- }
63
- }
64
- }
65
-
66
- impl Display for ParentScope {
67
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68
- match self {
69
- ParentScope::None => write!(f, "None"),
70
- ParentScope::TopLevel => write!(f, "TopLevel"),
71
- ParentScope::Some(id) => write!(f, "Some({id})"),
72
- ParentScope::Attached(id) => write!(f, "Attached({id})"),
73
- }
74
- }
75
- }
76
-
77
- #[derive(Debug, Clone, Eq)]
78
- pub struct Name {
79
- /// The unqualified name of the constant
80
- str: StringId,
81
- /// The ID of parent scope for this constant. For example:
82
- ///
83
- /// ```ruby
84
- /// Foo::Bar::Baz
85
- /// # ^ parent scope of Bar::Baz
86
- /// # ^ parent scope of Baz
87
- /// ```
88
- parent_scope: ParentScope,
89
- /// The ID of the name for the nesting where we found this name. This effectively turns the structure into a linked
90
- /// list of names to represent the nesting
91
- nesting: Option<NameId>,
92
- ref_count: u32,
93
- }
94
-
95
- impl PartialEq for Name {
96
- fn eq(&self, other: &Self) -> bool {
97
- self.str == other.str && self.parent_scope == other.parent_scope && self.nesting == other.nesting
98
- }
99
- }
100
- assert_mem_size!(Name, 40);
101
-
102
- impl Name {
103
- #[must_use]
104
- pub fn new(str: StringId, parent_scope: ParentScope, nesting: Option<NameId>) -> Self {
105
- Self {
106
- str,
107
- parent_scope,
108
- nesting,
109
- ref_count: 1,
110
- }
111
- }
112
-
113
- #[must_use]
114
- pub fn str(&self) -> &StringId {
115
- &self.str
116
- }
117
-
118
- #[must_use]
119
- pub fn parent_scope(&self) -> &ParentScope {
120
- &self.parent_scope
121
- }
122
-
123
- #[must_use]
124
- pub fn nesting(&self) -> &Option<NameId> {
125
- &self.nesting
126
- }
127
-
128
- #[must_use]
129
- pub fn id(&self) -> NameId {
130
- NameId::from(&format!(
131
- "{}{}{}",
132
- self.str,
133
- self.parent_scope,
134
- self.nesting.map_or(String::from("None"), |id| id.to_string())
135
- ))
136
- }
137
- }
138
-
139
- #[derive(Debug, Clone)]
140
- pub struct ResolvedName {
141
- name: Name,
142
- declaration_id: DeclarationId,
143
- }
144
-
145
- impl ResolvedName {
146
- #[must_use]
147
- pub fn new(name: Name, declaration_id: DeclarationId) -> Self {
148
- Self { name, declaration_id }
149
- }
150
-
151
- #[must_use]
152
- pub fn name(&self) -> &Name {
153
- &self.name
154
- }
155
-
156
- #[must_use]
157
- pub fn declaration_id(&self) -> &DeclarationId {
158
- &self.declaration_id
159
- }
160
-
161
- #[must_use]
162
- pub fn nesting(&self) -> &Option<NameId> {
163
- self.name.nesting()
164
- }
165
- }
166
-
167
- /// A usage of a constant name. This could be a constant reference or a definition like a class or module
168
- #[derive(Debug, Clone)]
169
- pub enum NameRef {
170
- /// This name has not yet been resolved. We don't yet know what this name refers to or if it refers to an existing
171
- /// declaration
172
- Unresolved(Box<Name>),
173
- /// This name has been resolved to an existing declaration
174
- Resolved(Box<ResolvedName>),
175
- }
176
-
177
- impl NameRef {
178
- #[must_use]
179
- pub fn str(&self) -> &StringId {
180
- match self {
181
- NameRef::Unresolved(name) => name.str(),
182
- NameRef::Resolved(resolved_name) => resolved_name.name.str(),
183
- }
184
- }
185
-
186
- #[must_use]
187
- pub fn parent_scope(&self) -> &ParentScope {
188
- match self {
189
- NameRef::Unresolved(name) => name.parent_scope(),
190
- NameRef::Resolved(resolved_name) => resolved_name.name.parent_scope(),
191
- }
192
- }
193
-
194
- #[must_use]
195
- pub fn into_unresolved(self) -> Option<Name> {
196
- match self {
197
- NameRef::Unresolved(name) => Some(*name),
198
- NameRef::Resolved(_) => None,
199
- }
200
- }
201
-
202
- #[must_use]
203
- pub fn nesting(&self) -> &Option<NameId> {
204
- match self {
205
- NameRef::Unresolved(name) => name.nesting(),
206
- NameRef::Resolved(resolved_name) => resolved_name.name.nesting(),
207
- }
208
- }
209
-
210
- #[must_use]
211
- pub fn ref_count(&self) -> u32 {
212
- match self {
213
- NameRef::Unresolved(name) => name.ref_count,
214
- NameRef::Resolved(resolved_name) => resolved_name.name.ref_count,
215
- }
216
- }
217
-
218
- /// # Panics
219
- ///
220
- /// Panics if we exceed the maximum size of the reference count
221
- pub fn increment_ref_count(&mut self, count: u32) {
222
- let ref_count = match self {
223
- NameRef::Unresolved(name) => &mut name.ref_count,
224
- NameRef::Resolved(resolved_name) => &mut resolved_name.name.ref_count,
225
- };
226
- *ref_count = ref_count
227
- .checked_add(count)
228
- .expect("Should not exceed maximum name ref count");
229
- }
230
-
231
- #[must_use]
232
- pub fn decrement_ref_count(&mut self) -> bool {
233
- match self {
234
- NameRef::Unresolved(name) => {
235
- name.ref_count -= 1;
236
- name.ref_count > 0
237
- }
238
- NameRef::Resolved(resolved_name) => {
239
- resolved_name.name.ref_count -= 1;
240
- resolved_name.name.ref_count > 0
241
- }
242
- }
243
- }
244
- }
245
-
246
- impl PartialEq for NameRef {
247
- fn eq(&self, other: &Self) -> bool {
248
- match (self, other) {
249
- (NameRef::Unresolved(a), NameRef::Unresolved(b)) => a == b,
250
- (NameRef::Resolved(a), NameRef::Resolved(b)) => a.name == b.name,
251
- (NameRef::Unresolved(name), NameRef::Resolved(resolved))
252
- | (NameRef::Resolved(resolved), NameRef::Unresolved(name)) => **name == resolved.name,
253
- }
254
- }
255
- }
256
-
257
- impl PartialEq<Name> for NameRef {
258
- fn eq(&self, other: &Name) -> bool {
259
- match self {
260
- NameRef::Unresolved(name) => **name == *other,
261
- NameRef::Resolved(resolved_name) => &resolved_name.name == other,
262
- }
263
- }
264
- }
265
-
266
- #[cfg(test)]
267
- mod tests {
268
- use super::*;
269
-
270
- #[test]
271
- fn same_parent_scope_and_nesting() {
272
- let name_1 = Name::new(StringId::from("Foo"), ParentScope::None, None);
273
- let name_2 = Name::new(StringId::from("Foo"), ParentScope::None, None);
274
- assert_eq!(name_1.id(), name_2.id());
275
-
276
- let name_3 = Name::new(StringId::from("Foo"), ParentScope::Some(name_1.id()), None);
277
- let name_4 = Name::new(StringId::from("Foo"), ParentScope::Some(name_2.id()), None);
278
- assert_eq!(name_3.id(), name_4.id());
279
-
280
- let name_5 = Name::new(StringId::from("Foo"), ParentScope::None, Some(name_1.id()));
281
- let name_6 = Name::new(StringId::from("Foo"), ParentScope::None, Some(name_2.id()));
282
- assert_eq!(name_5.id(), name_6.id());
283
- assert_ne!(name_3.id(), name_5.id());
284
- assert_ne!(name_4.id(), name_6.id());
285
-
286
- let name_7 = Name::new(
287
- StringId::from("Foo"),
288
- ParentScope::Some(Name::new(StringId::from("Foo"), ParentScope::None, None).id()),
289
- Some(Name::new(StringId::from("Foo"), ParentScope::None, None).id()),
290
- );
291
- let name_8 = Name::new(
292
- StringId::from("Foo"),
293
- ParentScope::Some(Name::new(StringId::from("Foo"), ParentScope::None, None).id()),
294
- Some(Name::new(StringId::from("Foo"), ParentScope::None, None).id()),
295
- );
296
- assert_eq!(name_7.id(), name_8.id());
297
- }
298
- }
1
+ use std::fmt::Display;
2
+
3
+ use crate::{
4
+ assert_mem_size,
5
+ model::ids::{DeclarationId, NameId, StringId},
6
+ };
7
+
8
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
9
+ pub enum ParentScope {
10
+ /// There's no parent scope in this reference (e.g.: `Foo`)
11
+ None,
12
+ /// There's an empty parent scope in this reference (e.g.: `::Foo`)
13
+ TopLevel,
14
+ /// There's a parent scope in this reference (e.g.: `Foo::Bar`)
15
+ Some(NameId),
16
+ /// Parent scope representing the class attached to a singleton class context
17
+ ///
18
+ /// `Foo::<Foo>::<<Foo>>`
19
+ /// ^ Attached for <Foo>
20
+ /// ^ Attached for <<Foo>>
21
+ Attached(NameId),
22
+ }
23
+ assert_mem_size!(ParentScope, 16);
24
+
25
+ impl ParentScope {
26
+ pub fn map_or<F, T>(&self, default: T, f: F) -> T
27
+ where
28
+ F: FnOnce(&NameId) -> T,
29
+ {
30
+ match self {
31
+ ParentScope::Some(id) | ParentScope::Attached(id) => f(id),
32
+ _ => default,
33
+ }
34
+ }
35
+
36
+ #[must_use]
37
+ pub fn as_ref(&self) -> Option<&NameId> {
38
+ match self {
39
+ ParentScope::Some(id) | ParentScope::Attached(id) => Some(id),
40
+ _ => None,
41
+ }
42
+ }
43
+
44
+ #[must_use]
45
+ pub fn is_none(&self) -> bool {
46
+ matches!(self, ParentScope::None)
47
+ }
48
+
49
+ #[must_use]
50
+ pub fn is_top_level(&self) -> bool {
51
+ matches!(self, ParentScope::TopLevel)
52
+ }
53
+
54
+ /// # Panics
55
+ ///
56
+ /// Panics if the `ParentScope` is None or `TopLevel`
57
+ #[must_use]
58
+ pub fn expect(&self, message: &str) -> NameId {
59
+ match self {
60
+ ParentScope::Some(id) | ParentScope::Attached(id) => *id,
61
+ _ => panic!("{}", message),
62
+ }
63
+ }
64
+ }
65
+
66
+ impl Display for ParentScope {
67
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68
+ match self {
69
+ ParentScope::None => write!(f, "None"),
70
+ ParentScope::TopLevel => write!(f, "TopLevel"),
71
+ ParentScope::Some(id) => write!(f, "Some({id})"),
72
+ ParentScope::Attached(id) => write!(f, "Attached({id})"),
73
+ }
74
+ }
75
+ }
76
+
77
+ #[derive(Debug, Clone, Eq)]
78
+ pub struct Name {
79
+ /// The unqualified name of the constant
80
+ str: StringId,
81
+ /// The ID of parent scope for this constant. For example:
82
+ ///
83
+ /// ```ruby
84
+ /// Foo::Bar::Baz
85
+ /// # ^ parent scope of Bar::Baz
86
+ /// # ^ parent scope of Baz
87
+ /// ```
88
+ parent_scope: ParentScope,
89
+ /// The ID of the name for the nesting where we found this name. This effectively turns the structure into a linked
90
+ /// list of names to represent the nesting
91
+ nesting: Option<NameId>,
92
+ ref_count: u32,
93
+ }
94
+
95
+ impl PartialEq for Name {
96
+ fn eq(&self, other: &Self) -> bool {
97
+ self.str == other.str && self.parent_scope == other.parent_scope && self.nesting == other.nesting
98
+ }
99
+ }
100
+ assert_mem_size!(Name, 40);
101
+
102
+ impl Name {
103
+ #[must_use]
104
+ pub fn new(str: StringId, parent_scope: ParentScope, nesting: Option<NameId>) -> Self {
105
+ Self {
106
+ str,
107
+ parent_scope,
108
+ nesting,
109
+ ref_count: 1,
110
+ }
111
+ }
112
+
113
+ #[must_use]
114
+ pub fn str(&self) -> &StringId {
115
+ &self.str
116
+ }
117
+
118
+ #[must_use]
119
+ pub fn parent_scope(&self) -> &ParentScope {
120
+ &self.parent_scope
121
+ }
122
+
123
+ #[must_use]
124
+ pub fn nesting(&self) -> &Option<NameId> {
125
+ &self.nesting
126
+ }
127
+
128
+ #[must_use]
129
+ pub fn id(&self) -> NameId {
130
+ NameId::from(&format!(
131
+ "{}{}{}",
132
+ self.str,
133
+ self.parent_scope,
134
+ self.nesting.map_or(String::from("None"), |id| id.to_string())
135
+ ))
136
+ }
137
+ }
138
+
139
+ #[derive(Debug, Clone)]
140
+ pub struct ResolvedName {
141
+ name: Name,
142
+ declaration_id: DeclarationId,
143
+ }
144
+
145
+ impl ResolvedName {
146
+ #[must_use]
147
+ pub fn new(name: Name, declaration_id: DeclarationId) -> Self {
148
+ Self { name, declaration_id }
149
+ }
150
+
151
+ #[must_use]
152
+ pub fn name(&self) -> &Name {
153
+ &self.name
154
+ }
155
+
156
+ #[must_use]
157
+ pub fn declaration_id(&self) -> &DeclarationId {
158
+ &self.declaration_id
159
+ }
160
+
161
+ #[must_use]
162
+ pub fn nesting(&self) -> &Option<NameId> {
163
+ self.name.nesting()
164
+ }
165
+ }
166
+
167
+ /// A usage of a constant name. This could be a constant reference or a definition like a class or module
168
+ #[derive(Debug, Clone)]
169
+ pub enum NameRef {
170
+ /// This name has not yet been resolved. We don't yet know what this name refers to or if it refers to an existing
171
+ /// declaration
172
+ Unresolved(Box<Name>),
173
+ /// This name has been resolved to an existing declaration
174
+ Resolved(Box<ResolvedName>),
175
+ }
176
+
177
+ impl NameRef {
178
+ #[must_use]
179
+ pub fn str(&self) -> &StringId {
180
+ match self {
181
+ NameRef::Unresolved(name) => name.str(),
182
+ NameRef::Resolved(resolved_name) => resolved_name.name.str(),
183
+ }
184
+ }
185
+
186
+ #[must_use]
187
+ pub fn parent_scope(&self) -> &ParentScope {
188
+ match self {
189
+ NameRef::Unresolved(name) => name.parent_scope(),
190
+ NameRef::Resolved(resolved_name) => resolved_name.name.parent_scope(),
191
+ }
192
+ }
193
+
194
+ #[must_use]
195
+ pub fn into_unresolved(self) -> Option<Name> {
196
+ match self {
197
+ NameRef::Unresolved(name) => Some(*name),
198
+ NameRef::Resolved(_) => None,
199
+ }
200
+ }
201
+
202
+ #[must_use]
203
+ pub fn nesting(&self) -> &Option<NameId> {
204
+ match self {
205
+ NameRef::Unresolved(name) => name.nesting(),
206
+ NameRef::Resolved(resolved_name) => resolved_name.name.nesting(),
207
+ }
208
+ }
209
+
210
+ #[must_use]
211
+ pub fn ref_count(&self) -> u32 {
212
+ match self {
213
+ NameRef::Unresolved(name) => name.ref_count,
214
+ NameRef::Resolved(resolved_name) => resolved_name.name.ref_count,
215
+ }
216
+ }
217
+
218
+ /// # Panics
219
+ ///
220
+ /// Panics if we exceed the maximum size of the reference count
221
+ pub fn increment_ref_count(&mut self, count: u32) {
222
+ let ref_count = match self {
223
+ NameRef::Unresolved(name) => &mut name.ref_count,
224
+ NameRef::Resolved(resolved_name) => &mut resolved_name.name.ref_count,
225
+ };
226
+ *ref_count = ref_count
227
+ .checked_add(count)
228
+ .expect("Should not exceed maximum name ref count");
229
+ }
230
+
231
+ #[must_use]
232
+ pub fn decrement_ref_count(&mut self) -> bool {
233
+ match self {
234
+ NameRef::Unresolved(name) => {
235
+ name.ref_count -= 1;
236
+ name.ref_count > 0
237
+ }
238
+ NameRef::Resolved(resolved_name) => {
239
+ resolved_name.name.ref_count -= 1;
240
+ resolved_name.name.ref_count > 0
241
+ }
242
+ }
243
+ }
244
+ }
245
+
246
+ impl PartialEq for NameRef {
247
+ fn eq(&self, other: &Self) -> bool {
248
+ match (self, other) {
249
+ (NameRef::Unresolved(a), NameRef::Unresolved(b)) => a == b,
250
+ (NameRef::Resolved(a), NameRef::Resolved(b)) => a.name == b.name,
251
+ (NameRef::Unresolved(name), NameRef::Resolved(resolved))
252
+ | (NameRef::Resolved(resolved), NameRef::Unresolved(name)) => **name == resolved.name,
253
+ }
254
+ }
255
+ }
256
+
257
+ impl PartialEq<Name> for NameRef {
258
+ fn eq(&self, other: &Name) -> bool {
259
+ match self {
260
+ NameRef::Unresolved(name) => **name == *other,
261
+ NameRef::Resolved(resolved_name) => &resolved_name.name == other,
262
+ }
263
+ }
264
+ }
265
+
266
+ #[cfg(test)]
267
+ mod tests {
268
+ use super::*;
269
+
270
+ #[test]
271
+ fn same_parent_scope_and_nesting() {
272
+ let name_1 = Name::new(StringId::from("Foo"), ParentScope::None, None);
273
+ let name_2 = Name::new(StringId::from("Foo"), ParentScope::None, None);
274
+ assert_eq!(name_1.id(), name_2.id());
275
+
276
+ let name_3 = Name::new(StringId::from("Foo"), ParentScope::Some(name_1.id()), None);
277
+ let name_4 = Name::new(StringId::from("Foo"), ParentScope::Some(name_2.id()), None);
278
+ assert_eq!(name_3.id(), name_4.id());
279
+
280
+ let name_5 = Name::new(StringId::from("Foo"), ParentScope::None, Some(name_1.id()));
281
+ let name_6 = Name::new(StringId::from("Foo"), ParentScope::None, Some(name_2.id()));
282
+ assert_eq!(name_5.id(), name_6.id());
283
+ assert_ne!(name_3.id(), name_5.id());
284
+ assert_ne!(name_4.id(), name_6.id());
285
+
286
+ let name_7 = Name::new(
287
+ StringId::from("Foo"),
288
+ ParentScope::Some(Name::new(StringId::from("Foo"), ParentScope::None, None).id()),
289
+ Some(Name::new(StringId::from("Foo"), ParentScope::None, None).id()),
290
+ );
291
+ let name_8 = Name::new(
292
+ StringId::from("Foo"),
293
+ ParentScope::Some(Name::new(StringId::from("Foo"), ParentScope::None, None).id()),
294
+ Some(Name::new(StringId::from("Foo"), ParentScope::None, None).id()),
295
+ );
296
+ assert_eq!(name_7.id(), name_8.id());
297
+ }
298
+ }