rubydex 0.2.9 → 0.4.0
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.
- checksums.yaml +4 -4
- data/README.md +110 -6
- data/THIRD_PARTY_LICENSES.html +271 -2
- data/exe/rdx +2 -73
- data/ext/rubydex/config.c +140 -0
- data/ext/rubydex/config.h +16 -0
- data/ext/rubydex/declaration.c +1 -1
- data/ext/rubydex/definition.c +32 -4
- data/ext/rubydex/diagnostic.c +75 -1
- data/ext/rubydex/diagnostic.h +2 -0
- data/ext/rubydex/graph.c +27 -48
- data/ext/rubydex/graph.h +6 -0
- data/ext/rubydex/query.c +487 -0
- data/ext/rubydex/query.h +8 -0
- data/ext/rubydex/reference.c +60 -0
- data/ext/rubydex/rubydex.c +4 -0
- data/ext/rubydex/utils.c +23 -4
- data/ext/rubydex/utils.h +5 -0
- data/lib/ruby_lsp/rubydex/addon.rb +211 -0
- data/lib/rubydex/cli/command/console.rb +55 -0
- data/lib/rubydex/cli/command/lint/explain.rb +74 -0
- data/lib/rubydex/cli/command/lint.rb +202 -0
- data/lib/rubydex/cli/command/mcp.rb +30 -0
- data/lib/rubydex/cli/command/query.rb +70 -0
- data/lib/rubydex/cli/command/skill.rb +69 -0
- data/lib/rubydex/cli/command.rb +168 -0
- data/lib/rubydex/cli.rb +93 -0
- data/lib/rubydex/config.rb +59 -0
- data/lib/rubydex/diagnostic.rb +12 -3
- data/lib/rubydex/errors.rb +42 -1
- data/lib/rubydex/graph.rb +10 -3
- data/lib/rubydex/linter/custom_rule.rb +97 -0
- data/lib/rubydex/linter/helpers/path_helpers.rb +78 -0
- data/lib/rubydex/linter/helpers/source_access_helpers.rb +31 -0
- data/lib/rubydex/linter/rule_loader.rb +36 -0
- data/lib/rubydex/linter/rule_test_case.rb +343 -0
- data/lib/rubydex/linter/runner.rb +56 -0
- data/lib/rubydex/linter.rb +19 -0
- data/lib/rubydex/location.rb +3 -0
- data/lib/rubydex/mcp_server.rb +1 -2
- data/lib/rubydex/related_information.rb +17 -0
- data/lib/rubydex/rule.rb +33 -0
- data/lib/rubydex/severity.rb +70 -0
- data/lib/rubydex/skill.rb +88 -0
- data/lib/rubydex/skill_registry.rb +62 -0
- data/lib/rubydex/version.rb +1 -1
- data/lib/rubydex.rb +6 -0
- data/lib/rubydex_linter/rules/rule_structure.rb +125 -0
- data/rbi/rubydex.rbi +578 -15
- data/rust/Cargo.lock +7 -0
- data/rust/rubydex/Cargo.toml +1 -0
- data/rust/rubydex/benches/graph_memory.rs +20 -4
- data/rust/rubydex/src/compile_assertions.rs +15 -0
- data/rust/rubydex/src/config.rs +538 -157
- data/rust/rubydex/src/diagnostic.rs +66 -40
- data/rust/rubydex/src/errors.rs +0 -1
- data/rust/rubydex/src/indexing/local_graph.rs +6 -5
- data/rust/rubydex/src/indexing/rbs_indexer.rs +284 -8
- data/rust/rubydex/src/indexing/ruby_indexer.rs +59 -70
- data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +195 -86
- data/rust/rubydex/src/lib.rs +1 -0
- data/rust/rubydex/src/listing.rs +26 -1
- data/rust/rubydex/src/main.rs +9 -128
- data/rust/rubydex/src/model/declaration.rs +301 -229
- data/rust/rubydex/src/model/definitions.rs +27 -26
- data/rust/rubydex/src/model/document.rs +43 -7
- data/rust/rubydex/src/model/graph.rs +67 -68
- data/rust/rubydex/src/model/id.rs +55 -0
- data/rust/rubydex/src/model/ids.rs +21 -9
- data/rust/rubydex/src/model/name.rs +88 -19
- data/rust/rubydex/src/model/references.rs +16 -13
- data/rust/rubydex/src/operation/ruby_builder.rs +78 -104
- data/rust/rubydex/src/path_helpers.rs +77 -0
- data/rust/rubydex/src/query/cypher/schema.rs +853 -0
- data/rust/rubydex/src/query/cypher/schema_info.rs +161 -0
- data/rust/rubydex/src/query/cypher/tests.rs +253 -0
- data/rust/rubydex/src/query/cypher.rs +54 -0
- data/rust/rubydex/src/query.rs +125 -43
- data/rust/rubydex/src/resolution.rs +368 -395
- data/rust/rubydex/src/resolution_tests.rs +504 -78
- data/rust/rubydex/src/test_utils/context.rs +2 -1
- data/rust/rubydex/src/test_utils/graph_test.rs +26 -12
- data/rust/rubydex/src/test_utils/local_graph_test.rs +19 -0
- data/rust/rubydex/tests/cli.rs +4 -4
- data/rust/rubydex-sys/src/config_api.rs +205 -0
- data/rust/rubydex-sys/src/cypher_api.rs +791 -0
- data/rust/rubydex-sys/src/declaration_api.rs +6 -3
- data/rust/rubydex-sys/src/definition_api.rs +27 -7
- data/rust/rubydex-sys/src/diagnostic_api.rs +77 -8
- data/rust/rubydex-sys/src/graph_api.rs +31 -68
- data/rust/rubydex-sys/src/lib.rs +2 -0
- data/rust/rubydex-sys/src/name_api.rs +2 -6
- data/rust/rubydex-sys/src/reference_api.rs +58 -12
- data/rust/rubydex-sys/src/utils.rs +37 -0
- data/skills/send-private-method/SKILL.md +133 -0
- metadata +37 -2
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
use std::hash::Hash;
|
|
2
|
+
|
|
1
3
|
use crate::assert_mem_size;
|
|
2
4
|
use crate::model::ids::{
|
|
3
5
|
ClassVariableReferenceId, GlobalVariableReferenceId, InstanceVariableReferenceId, MethodReferenceId,
|
|
@@ -57,23 +59,6 @@ impl<'a> IntoIterator for &'a Ancestors {
|
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
macro_rules! all_declarations {
|
|
61
|
-
($value:expr, $var:ident => $expr:expr) => {
|
|
62
|
-
match $value {
|
|
63
|
-
Declaration::Namespace(Namespace::Class($var)) => $expr,
|
|
64
|
-
Declaration::Namespace(Namespace::Module($var)) => $expr,
|
|
65
|
-
Declaration::Namespace(Namespace::SingletonClass($var)) => $expr,
|
|
66
|
-
Declaration::Namespace(Namespace::Todo($var)) => $expr,
|
|
67
|
-
Declaration::Constant($var) => $expr,
|
|
68
|
-
Declaration::ConstantAlias($var) => $expr,
|
|
69
|
-
Declaration::Method($var) => $expr,
|
|
70
|
-
Declaration::GlobalVariable($var) => $expr,
|
|
71
|
-
Declaration::InstanceVariable($var) => $expr,
|
|
72
|
-
Declaration::ClassVariable($var) => $expr,
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
62
|
macro_rules! all_namespaces {
|
|
78
63
|
($value:expr, $var:ident => $expr:expr) => {
|
|
79
64
|
match $value {
|
|
@@ -90,56 +75,29 @@ macro_rules! namespace_declaration {
|
|
|
90
75
|
($variant:ident, $name:ident) => {
|
|
91
76
|
#[derive(Debug)]
|
|
92
77
|
pub struct $name {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
/// The list of definition IDs that compose this declaration
|
|
96
|
-
definition_ids: Vec<DefinitionId>,
|
|
97
|
-
/// The set of references that are made to this declaration
|
|
98
|
-
references: IdentityHashSet<ConstantReferenceId>,
|
|
99
|
-
/// The ID of the owner of this declaration. For singleton classes, this is the ID of the attached object
|
|
100
|
-
owner_id: DeclarationId,
|
|
101
|
-
/// The entities that are owned by this declaration. For example, constants and methods that are defined inside of
|
|
102
|
-
/// the namespace. Note that this is a hashmap of unqualified name IDs to declaration IDs. That assists the
|
|
103
|
-
/// traversal of the graph when trying to resolve constant references or trying to discover which methods exist in a
|
|
104
|
-
/// class
|
|
105
|
-
members: IdentityHashMap<StringId, DeclarationId>,
|
|
106
|
-
/// The linearized ancestor chain for this declaration. These are the other declarations that this
|
|
107
|
-
/// declaration inherits from
|
|
108
|
-
ancestors: Ancestors,
|
|
109
|
-
/// The set of declarations that inherit from this declaration
|
|
110
|
-
descendants: IdentityHashSet<DeclarationId>,
|
|
111
|
-
/// The singleton class associated with this declaration
|
|
112
|
-
singleton_class_id: Option<DeclarationId>,
|
|
78
|
+
core: DeclarationCore<ConstantReferenceId>,
|
|
79
|
+
namespace_store: NamespaceStore,
|
|
113
80
|
}
|
|
114
81
|
|
|
115
82
|
impl $name {
|
|
116
83
|
#[must_use]
|
|
117
84
|
pub fn new(name: String, owner_id: DeclarationId) -> Self {
|
|
118
85
|
Self {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
members: IdentityHashMap::default(),
|
|
122
|
-
references: IdentityHashSet::default(),
|
|
123
|
-
owner_id,
|
|
124
|
-
ancestors: Ancestors::Partial(Vec::new()),
|
|
125
|
-
descendants: IdentityHashSet::default(),
|
|
126
|
-
singleton_class_id: None,
|
|
86
|
+
core: DeclarationCore::new(name, owner_id),
|
|
87
|
+
namespace_store: NamespaceStore::new(),
|
|
127
88
|
}
|
|
128
89
|
}
|
|
129
90
|
|
|
130
91
|
pub fn extend(&mut self, other: Declaration) {
|
|
131
|
-
self.definition_ids.extend(other.definitions());
|
|
92
|
+
self.core.definition_ids.extend(other.definitions());
|
|
132
93
|
|
|
133
94
|
match other {
|
|
134
95
|
Declaration::Namespace(namespace) => {
|
|
135
|
-
self.members.extend(namespace.members());
|
|
136
|
-
self.references.extend(namespace.references());
|
|
137
|
-
}
|
|
138
|
-
Declaration::Constant(constant) => {
|
|
139
|
-
self.references.extend(constant.references());
|
|
96
|
+
self.namespace_store.members.extend(namespace.members());
|
|
97
|
+
self.core.references.extend(namespace.references());
|
|
140
98
|
}
|
|
141
|
-
Declaration::ConstantAlias(
|
|
142
|
-
self.references.extend(
|
|
99
|
+
Declaration::Constant(it) | Declaration::ConstantAlias(it) => {
|
|
100
|
+
self.core.references.extend(it.references());
|
|
143
101
|
}
|
|
144
102
|
Declaration::Method(_)
|
|
145
103
|
| Declaration::GlobalVariable(_)
|
|
@@ -149,132 +107,198 @@ macro_rules! namespace_declaration {
|
|
|
149
107
|
}
|
|
150
108
|
}
|
|
151
109
|
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}
|
|
152
113
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
114
|
+
/// The core data of a declaration, shared across all of them
|
|
115
|
+
#[derive(Debug)]
|
|
116
|
+
pub struct DeclarationCore<T> {
|
|
117
|
+
/// The fully qualified name of this declaration
|
|
118
|
+
name: Box<str>,
|
|
119
|
+
/// The list of definition IDs that compose this declaration
|
|
120
|
+
definition_ids: Vec<DefinitionId>,
|
|
121
|
+
/// The set of references that are made to this declaration
|
|
122
|
+
references: IdentityHashSet<T>,
|
|
123
|
+
/// The ID of the owner of this declaration
|
|
124
|
+
owner_id: DeclarationId,
|
|
125
|
+
}
|
|
156
126
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
127
|
+
impl<T: Eq + Hash> DeclarationCore<T> {
|
|
128
|
+
#[must_use]
|
|
129
|
+
pub fn new(name: String, owner_id: DeclarationId) -> Self {
|
|
130
|
+
Self {
|
|
131
|
+
name: name.into_boxed_str(),
|
|
132
|
+
definition_ids: Vec::new(),
|
|
133
|
+
references: IdentityHashSet::default(),
|
|
134
|
+
owner_id,
|
|
135
|
+
}
|
|
136
|
+
}
|
|
160
137
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
138
|
+
#[must_use]
|
|
139
|
+
pub fn name(&self) -> &str {
|
|
140
|
+
&self.name
|
|
141
|
+
}
|
|
164
142
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
143
|
+
#[must_use]
|
|
144
|
+
pub fn unqualified_name(&self) -> String {
|
|
145
|
+
let after_colons = self.name.rsplit("::").next().unwrap_or(&self.name);
|
|
146
|
+
after_colons.rsplit('#').next().unwrap_or(after_colons).to_string()
|
|
147
|
+
}
|
|
168
148
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
149
|
+
pub fn extend(&mut self, other: Self) {
|
|
150
|
+
self.definition_ids.extend(other.definition_ids);
|
|
151
|
+
self.references.extend(other.references);
|
|
152
|
+
}
|
|
173
153
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
154
|
+
#[must_use]
|
|
155
|
+
pub fn references(&self) -> &IdentityHashSet<T> {
|
|
156
|
+
&self.references
|
|
157
|
+
}
|
|
177
158
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
159
|
+
pub fn add_reference(&mut self, reference_id: T) {
|
|
160
|
+
self.references.insert(reference_id);
|
|
161
|
+
}
|
|
181
162
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
163
|
+
pub fn remove_reference(&mut self, reference_id: &T) {
|
|
164
|
+
self.references.remove(reference_id);
|
|
165
|
+
}
|
|
186
166
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
167
|
+
#[must_use]
|
|
168
|
+
pub fn has_no_definitions(&self) -> bool {
|
|
169
|
+
self.definition_ids.is_empty()
|
|
170
|
+
}
|
|
190
171
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
172
|
+
#[must_use]
|
|
173
|
+
pub fn definitions(&self) -> &[DefinitionId] {
|
|
174
|
+
&self.definition_ids
|
|
175
|
+
}
|
|
194
176
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
177
|
+
pub fn add_definition(&mut self, definition_id: DefinitionId) {
|
|
178
|
+
debug_assert!(
|
|
179
|
+
!self.definition_ids.contains(&definition_id),
|
|
180
|
+
"Cannot add the same exact definition to a declaration twice. Duplicate definition IDs"
|
|
181
|
+
);
|
|
198
182
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
self.ancestors.clone()
|
|
202
|
-
}
|
|
183
|
+
self.definition_ids.push(definition_id);
|
|
184
|
+
}
|
|
203
185
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
186
|
+
pub fn remove_definition(&mut self, definition_id: &DefinitionId) -> bool {
|
|
187
|
+
if let Some(pos) = self.definition_ids.iter().position(|id| id == definition_id) {
|
|
188
|
+
self.definition_ids.swap_remove(pos);
|
|
189
|
+
self.definition_ids.shrink_to_fit();
|
|
190
|
+
true
|
|
191
|
+
} else {
|
|
192
|
+
false
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
208
196
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
197
|
+
/// Storage for namespace data, like ancestors, descendants, members and singleton class
|
|
198
|
+
#[derive(Debug)]
|
|
199
|
+
pub struct NamespaceStore {
|
|
200
|
+
/// The entities that are owned by this declaration. For example, constants and methods that are defined inside of
|
|
201
|
+
/// the namespace. Note that this is a hashmap of unqualified name IDs to declaration IDs. That assists the
|
|
202
|
+
/// traversal of the graph when trying to resolve constant references or trying to discover which methods exist in a
|
|
203
|
+
/// class
|
|
204
|
+
members: IdentityHashMap<StringId, DeclarationId>,
|
|
205
|
+
/// The linearized ancestor chain for this declaration. These are the other declarations that this
|
|
206
|
+
/// declaration inherits from
|
|
207
|
+
ancestors: Ancestors,
|
|
208
|
+
/// The set of declarations that inherit from this declaration
|
|
209
|
+
descendants: IdentityHashSet<DeclarationId>,
|
|
210
|
+
/// The singleton class associated with this declaration
|
|
211
|
+
singleton_class_id: Option<DeclarationId>,
|
|
212
|
+
}
|
|
212
213
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
impl NamespaceStore {
|
|
215
|
+
#[must_use]
|
|
216
|
+
pub fn new() -> Self {
|
|
217
|
+
Self {
|
|
218
|
+
members: IdentityHashMap::default(),
|
|
219
|
+
ancestors: Ancestors::Partial(Vec::new()),
|
|
220
|
+
descendants: IdentityHashSet::default(),
|
|
221
|
+
singleton_class_id: None,
|
|
222
|
+
}
|
|
223
|
+
}
|
|
216
224
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
225
|
+
pub fn extend(&mut self, other: Self) {
|
|
226
|
+
self.members.extend(other.members);
|
|
227
|
+
self.descendants.extend(other.descendants);
|
|
228
|
+
}
|
|
220
229
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
}
|
|
230
|
+
pub fn set_singleton_class_id(&mut self, declaration_id: DeclarationId) {
|
|
231
|
+
self.singleton_class_id = Some(declaration_id);
|
|
232
|
+
}
|
|
227
233
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
#[derive(Debug)]
|
|
232
|
-
pub struct $name {
|
|
233
|
-
/// The fully qualified name of this declaration
|
|
234
|
-
name: Box<str>,
|
|
235
|
-
/// The list of definition IDs that compose this declaration
|
|
236
|
-
definition_ids: Vec<DefinitionId>,
|
|
237
|
-
/// The set of references that are made to this declaration
|
|
238
|
-
references: IdentityHashSet<$reference_type>,
|
|
239
|
-
/// The ID of the owner of this declaration
|
|
240
|
-
owner_id: DeclarationId,
|
|
241
|
-
}
|
|
234
|
+
pub fn clear_singleton_class_id(&mut self) {
|
|
235
|
+
self.singleton_class_id = None;
|
|
236
|
+
}
|
|
242
237
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
name: name.into_boxed_str(),
|
|
248
|
-
definition_ids: Vec::new(),
|
|
249
|
-
references: IdentityHashSet::default(),
|
|
250
|
-
owner_id,
|
|
251
|
-
}
|
|
252
|
-
}
|
|
238
|
+
#[must_use]
|
|
239
|
+
pub fn singleton_class_id(&self) -> Option<&DeclarationId> {
|
|
240
|
+
self.singleton_class_id.as_ref()
|
|
241
|
+
}
|
|
253
242
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
243
|
+
#[must_use]
|
|
244
|
+
pub fn members(&self) -> &IdentityHashMap<StringId, DeclarationId> {
|
|
245
|
+
&self.members
|
|
246
|
+
}
|
|
258
247
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
248
|
+
pub fn add_member(&mut self, string_id: StringId, declaration_id: DeclarationId) {
|
|
249
|
+
self.members.insert(string_id, declaration_id);
|
|
250
|
+
}
|
|
263
251
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
252
|
+
pub fn remove_member(&mut self, string_id: &StringId) -> Option<DeclarationId> {
|
|
253
|
+
self.members.remove(string_id)
|
|
254
|
+
}
|
|
267
255
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
256
|
+
#[must_use]
|
|
257
|
+
pub fn member(&self, string_id: &StringId) -> Option<&DeclarationId> {
|
|
258
|
+
self.members.get(string_id)
|
|
259
|
+
}
|
|
271
260
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
261
|
+
pub fn set_ancestors(&mut self, ancestors: Ancestors) {
|
|
262
|
+
self.ancestors = ancestors;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
#[must_use]
|
|
266
|
+
pub fn ancestors(&self) -> &Ancestors {
|
|
267
|
+
&self.ancestors
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
#[must_use]
|
|
271
|
+
pub fn clone_ancestors(&self) -> Ancestors {
|
|
272
|
+
self.ancestors.clone()
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
#[must_use]
|
|
276
|
+
pub fn has_complete_ancestors(&self) -> bool {
|
|
277
|
+
matches!(&self.ancestors, Ancestors::Complete(_) | Ancestors::Cyclic(_))
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
pub fn add_descendant(&mut self, descendant_id: DeclarationId) {
|
|
281
|
+
self.descendants.insert(descendant_id);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
fn remove_descendant(&mut self, descendant_id: DeclarationId) {
|
|
285
|
+
self.descendants.remove(&descendant_id);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
pub fn clear_descendants(&mut self) {
|
|
289
|
+
self.descendants.clear();
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
#[must_use]
|
|
293
|
+
pub fn descendants(&self) -> &IdentityHashSet<DeclarationId> {
|
|
294
|
+
&self.descendants
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
impl Default for NamespaceStore {
|
|
299
|
+
fn default() -> Self {
|
|
300
|
+
Self::new()
|
|
301
|
+
}
|
|
278
302
|
}
|
|
279
303
|
|
|
280
304
|
/// A `Declaration` represents the global concept of an entity in Ruby. For example, the class `Foo` may be defined 3
|
|
@@ -295,7 +319,14 @@ assert_mem_size!(Declaration, 16);
|
|
|
295
319
|
impl Declaration {
|
|
296
320
|
#[must_use]
|
|
297
321
|
pub fn name(&self) -> &str {
|
|
298
|
-
|
|
322
|
+
match self {
|
|
323
|
+
Self::Namespace(namespace) => namespace.core().name(),
|
|
324
|
+
Self::ConstantAlias(it) | Self::Constant(it) => it.name(),
|
|
325
|
+
Self::Method(it) => it.name(),
|
|
326
|
+
Self::GlobalVariable(it) => it.name(),
|
|
327
|
+
Self::InstanceVariable(it) => it.name(),
|
|
328
|
+
Self::ClassVariable(it) => it.name(),
|
|
329
|
+
}
|
|
299
330
|
}
|
|
300
331
|
|
|
301
332
|
#[must_use]
|
|
@@ -377,55 +408,86 @@ impl Declaration {
|
|
|
377
408
|
|
|
378
409
|
#[must_use]
|
|
379
410
|
pub fn definitions(&self) -> &[DefinitionId] {
|
|
380
|
-
|
|
411
|
+
match self {
|
|
412
|
+
Self::Namespace(namespace) => namespace.core().definitions(),
|
|
413
|
+
Self::Constant(it) | Self::ConstantAlias(it) => it.definitions(),
|
|
414
|
+
Self::Method(it) => it.definitions(),
|
|
415
|
+
Self::GlobalVariable(it) => it.definitions(),
|
|
416
|
+
Self::InstanceVariable(it) => it.definitions(),
|
|
417
|
+
Self::ClassVariable(it) => it.definitions(),
|
|
418
|
+
}
|
|
381
419
|
}
|
|
382
420
|
|
|
383
421
|
#[must_use]
|
|
384
422
|
pub fn has_no_definitions(&self) -> bool {
|
|
385
|
-
|
|
423
|
+
match self {
|
|
424
|
+
Self::Namespace(namespace) => namespace.core().has_no_definitions(),
|
|
425
|
+
Self::Constant(it) | Self::ConstantAlias(it) => it.has_no_definitions(),
|
|
426
|
+
Self::Method(it) => it.has_no_definitions(),
|
|
427
|
+
Self::GlobalVariable(it) => it.has_no_definitions(),
|
|
428
|
+
Self::InstanceVariable(it) => it.has_no_definitions(),
|
|
429
|
+
Self::ClassVariable(it) => it.has_no_definitions(),
|
|
430
|
+
}
|
|
386
431
|
}
|
|
387
432
|
|
|
388
433
|
pub fn add_definition(&mut self, definition_id: DefinitionId) {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
)
|
|
394
|
-
|
|
395
|
-
it.
|
|
396
|
-
}
|
|
434
|
+
match self {
|
|
435
|
+
Self::Namespace(namespace) => namespace.core_mut().add_definition(definition_id),
|
|
436
|
+
Self::Constant(it) | Self::ConstantAlias(it) => it.add_definition(definition_id),
|
|
437
|
+
Self::Method(it) => it.add_definition(definition_id),
|
|
438
|
+
Self::GlobalVariable(it) => it.add_definition(definition_id),
|
|
439
|
+
Self::InstanceVariable(it) => it.add_definition(definition_id),
|
|
440
|
+
Self::ClassVariable(it) => it.add_definition(definition_id),
|
|
441
|
+
}
|
|
397
442
|
}
|
|
398
443
|
|
|
399
444
|
// Deletes a definition from this declaration
|
|
400
445
|
pub fn remove_definition(&mut self, definition_id: &DefinitionId) -> bool {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
})
|
|
446
|
+
match self {
|
|
447
|
+
Self::Namespace(namespace) => namespace.core_mut().remove_definition(definition_id),
|
|
448
|
+
Self::Constant(it) | Self::ConstantAlias(it) => it.remove_definition(definition_id),
|
|
449
|
+
Self::Method(it) => it.remove_definition(definition_id),
|
|
450
|
+
Self::GlobalVariable(it) => it.remove_definition(definition_id),
|
|
451
|
+
Self::InstanceVariable(it) => it.remove_definition(definition_id),
|
|
452
|
+
Self::ClassVariable(it) => it.remove_definition(definition_id),
|
|
453
|
+
}
|
|
410
454
|
}
|
|
411
455
|
|
|
412
456
|
#[must_use]
|
|
413
457
|
pub fn owner_id(&self) -> &DeclarationId {
|
|
414
|
-
|
|
458
|
+
match self {
|
|
459
|
+
Self::Namespace(namespace) => &namespace.core().owner_id,
|
|
460
|
+
Self::Constant(it) | Self::ConstantAlias(it) => &it.owner_id,
|
|
461
|
+
Self::Method(it) => &it.owner_id,
|
|
462
|
+
Self::GlobalVariable(it) => &it.owner_id,
|
|
463
|
+
Self::InstanceVariable(it) => &it.owner_id,
|
|
464
|
+
Self::ClassVariable(it) => &it.owner_id,
|
|
465
|
+
}
|
|
415
466
|
}
|
|
416
467
|
|
|
417
468
|
// Splits the fully qualified name either in the last `::` or the `#` to return the simple name of this declaration
|
|
418
469
|
#[must_use]
|
|
419
470
|
pub fn unqualified_name(&self) -> String {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
471
|
+
match self {
|
|
472
|
+
Self::Namespace(namespace) => namespace.core().unqualified_name(),
|
|
473
|
+
Self::Constant(it) | Self::ConstantAlias(it) => it.unqualified_name(),
|
|
474
|
+
Self::Method(it) => it.unqualified_name(),
|
|
475
|
+
Self::GlobalVariable(it) => it.unqualified_name(),
|
|
476
|
+
Self::InstanceVariable(it) => it.unqualified_name(),
|
|
477
|
+
Self::ClassVariable(it) => it.unqualified_name(),
|
|
478
|
+
}
|
|
424
479
|
}
|
|
425
480
|
|
|
426
481
|
#[must_use]
|
|
427
482
|
pub fn reference_count(&self) -> usize {
|
|
428
|
-
|
|
483
|
+
match self {
|
|
484
|
+
Self::Namespace(namespace) => namespace.core().references.len(),
|
|
485
|
+
Self::Constant(it) | Self::ConstantAlias(it) => it.references.len(),
|
|
486
|
+
Self::Method(it) => it.references.len(),
|
|
487
|
+
Self::GlobalVariable(it) => it.references.len(),
|
|
488
|
+
Self::InstanceVariable(it) => it.references.len(),
|
|
489
|
+
Self::ClassVariable(it) => it.references.len(),
|
|
490
|
+
}
|
|
429
491
|
}
|
|
430
492
|
|
|
431
493
|
/// Returns the constant reference IDs for declarations that track constant references (`Namespace`, `Constant`,
|
|
@@ -434,8 +496,7 @@ impl Declaration {
|
|
|
434
496
|
pub fn constant_references(&self) -> Option<&IdentityHashSet<ConstantReferenceId>> {
|
|
435
497
|
match self {
|
|
436
498
|
Declaration::Namespace(it) => Some(it.references()),
|
|
437
|
-
Declaration::Constant(it) => Some(it.references()),
|
|
438
|
-
Declaration::ConstantAlias(it) => Some(it.references()),
|
|
499
|
+
Declaration::Constant(it) | Declaration::ConstantAlias(it) => Some(it.references()),
|
|
439
500
|
_ => None,
|
|
440
501
|
}
|
|
441
502
|
}
|
|
@@ -448,8 +509,7 @@ impl Declaration {
|
|
|
448
509
|
pub fn add_constant_reference(&mut self, reference_id: ConstantReferenceId) {
|
|
449
510
|
match self {
|
|
450
511
|
Declaration::Namespace(it) => it.add_reference(reference_id),
|
|
451
|
-
Declaration::Constant(it) => it.add_reference(reference_id),
|
|
452
|
-
Declaration::ConstantAlias(it) => it.add_reference(reference_id),
|
|
512
|
+
Declaration::Constant(it) | Declaration::ConstantAlias(it) => it.add_reference(reference_id),
|
|
453
513
|
_ => unreachable!("Cannot add constant reference to {} declaration", self.kind()),
|
|
454
514
|
}
|
|
455
515
|
}
|
|
@@ -462,8 +522,7 @@ impl Declaration {
|
|
|
462
522
|
pub fn remove_constant_reference(&mut self, reference_id: &ConstantReferenceId) {
|
|
463
523
|
match self {
|
|
464
524
|
Declaration::Namespace(it) => it.remove_reference(reference_id),
|
|
465
|
-
Declaration::Constant(it) => it.remove_reference(reference_id),
|
|
466
|
-
Declaration::ConstantAlias(it) => it.remove_reference(reference_id),
|
|
525
|
+
Declaration::Constant(it) | Declaration::ConstantAlias(it) => it.remove_reference(reference_id),
|
|
467
526
|
_ => unreachable!("Cannot remove constant reference from {} declaration", self.kind()),
|
|
468
527
|
}
|
|
469
528
|
}
|
|
@@ -479,6 +538,16 @@ pub enum Namespace {
|
|
|
479
538
|
assert_mem_size!(Namespace, 16);
|
|
480
539
|
|
|
481
540
|
impl Namespace {
|
|
541
|
+
#[must_use]
|
|
542
|
+
pub fn core(&self) -> &DeclarationCore<ConstantReferenceId> {
|
|
543
|
+
all_namespaces!(self, it => &it.core)
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
#[must_use]
|
|
547
|
+
pub fn core_mut(&mut self) -> &mut DeclarationCore<ConstantReferenceId> {
|
|
548
|
+
all_namespaces!(self, it => &mut it.core)
|
|
549
|
+
}
|
|
550
|
+
|
|
482
551
|
#[must_use]
|
|
483
552
|
pub fn kind(&self) -> &'static str {
|
|
484
553
|
match self {
|
|
@@ -491,29 +560,29 @@ impl Namespace {
|
|
|
491
560
|
|
|
492
561
|
#[must_use]
|
|
493
562
|
pub fn references(&self) -> &IdentityHashSet<ConstantReferenceId> {
|
|
494
|
-
all_namespaces!(self, it => &it.references)
|
|
563
|
+
all_namespaces!(self, it => &it.core.references)
|
|
495
564
|
}
|
|
496
565
|
|
|
497
566
|
pub fn remove_reference(&mut self, reference_id: &ConstantReferenceId) {
|
|
498
567
|
all_namespaces!(self, it => {
|
|
499
|
-
it.
|
|
568
|
+
it.core.remove_reference(reference_id);
|
|
500
569
|
});
|
|
501
570
|
}
|
|
502
571
|
|
|
503
572
|
pub fn add_reference(&mut self, reference_id: ConstantReferenceId) {
|
|
504
573
|
all_namespaces!(self, it => {
|
|
505
|
-
it.
|
|
574
|
+
it.core.add_reference(reference_id);
|
|
506
575
|
});
|
|
507
576
|
}
|
|
508
577
|
|
|
509
578
|
#[must_use]
|
|
510
579
|
pub fn definitions(&self) -> &[DefinitionId] {
|
|
511
|
-
all_namespaces!(self, it => &it.
|
|
580
|
+
all_namespaces!(self, it => &it.core.definitions())
|
|
512
581
|
}
|
|
513
582
|
|
|
514
583
|
#[must_use]
|
|
515
584
|
pub fn members(&self) -> &IdentityHashMap<StringId, DeclarationId> {
|
|
516
|
-
all_namespaces!(self, it => &it.members)
|
|
585
|
+
all_namespaces!(self, it => &it.namespace_store.members)
|
|
517
586
|
}
|
|
518
587
|
|
|
519
588
|
pub fn extend(&mut self, other: Declaration) {
|
|
@@ -522,88 +591,85 @@ impl Namespace {
|
|
|
522
591
|
|
|
523
592
|
#[must_use]
|
|
524
593
|
pub fn ancestors(&self) -> &Ancestors {
|
|
525
|
-
all_namespaces!(self, it => it.ancestors())
|
|
594
|
+
all_namespaces!(self, it => it.namespace_store.ancestors())
|
|
526
595
|
}
|
|
527
596
|
|
|
528
597
|
#[must_use]
|
|
529
598
|
pub fn clone_ancestors(&self) -> Ancestors {
|
|
530
|
-
all_namespaces!(self, it => it.clone_ancestors())
|
|
599
|
+
all_namespaces!(self, it => it.namespace_store.clone_ancestors())
|
|
531
600
|
}
|
|
532
601
|
|
|
533
602
|
pub fn set_ancestors(&mut self, ancestors: Ancestors) {
|
|
534
|
-
all_namespaces!(self, it => it.set_ancestors(ancestors));
|
|
603
|
+
all_namespaces!(self, it => it.namespace_store.set_ancestors(ancestors));
|
|
535
604
|
}
|
|
536
605
|
|
|
537
606
|
#[must_use]
|
|
538
607
|
pub fn has_complete_ancestors(&self) -> bool {
|
|
539
|
-
all_namespaces!(self, it => it.has_complete_ancestors())
|
|
608
|
+
all_namespaces!(self, it => it.namespace_store.has_complete_ancestors())
|
|
540
609
|
}
|
|
541
610
|
|
|
542
611
|
#[must_use]
|
|
543
612
|
pub fn descendants(&self) -> &IdentityHashSet<DeclarationId> {
|
|
544
|
-
all_namespaces!(self, it => it.descendants())
|
|
613
|
+
all_namespaces!(self, it => it.namespace_store.descendants())
|
|
545
614
|
}
|
|
546
615
|
|
|
547
616
|
pub fn add_descendant(&mut self, descendant_id: DeclarationId) {
|
|
548
|
-
all_namespaces!(self, it => it.add_descendant(descendant_id));
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
pub fn remove_descendant(&mut self, descendant_id: &DeclarationId) {
|
|
552
|
-
all_namespaces!(self, it => it.remove_descendant(descendant_id));
|
|
617
|
+
all_namespaces!(self, it => it.namespace_store.add_descendant(descendant_id));
|
|
553
618
|
}
|
|
554
619
|
|
|
555
|
-
pub fn
|
|
556
|
-
|
|
557
|
-
F: FnMut(&Ancestor),
|
|
558
|
-
{
|
|
559
|
-
all_namespaces!(self, it => it.ancestors().iter().for_each(&mut f));
|
|
620
|
+
pub fn remove_descendant(&mut self, descendant_id: DeclarationId) {
|
|
621
|
+
all_namespaces!(self, it => it.namespace_store.remove_descendant(descendant_id));
|
|
560
622
|
}
|
|
561
623
|
|
|
562
624
|
pub fn for_each_descendant<F>(&self, mut f: F)
|
|
563
625
|
where
|
|
564
626
|
F: FnMut(&DeclarationId),
|
|
565
627
|
{
|
|
566
|
-
all_namespaces!(self, it => it.descendants().iter().for_each(&mut f));
|
|
628
|
+
all_namespaces!(self, it => it.namespace_store.descendants().iter().for_each(&mut f));
|
|
567
629
|
}
|
|
568
630
|
|
|
569
631
|
pub fn clear_ancestors(&mut self) {
|
|
570
|
-
all_namespaces!(self, it => it.set_ancestors(Ancestors::Partial(vec![])));
|
|
632
|
+
all_namespaces!(self, it => it.namespace_store.set_ancestors(Ancestors::Partial(vec![])));
|
|
571
633
|
}
|
|
572
634
|
|
|
573
635
|
pub fn clear_descendants(&mut self) {
|
|
574
|
-
all_namespaces!(self, it => it.clear_descendants());
|
|
636
|
+
all_namespaces!(self, it => it.namespace_store.clear_descendants());
|
|
575
637
|
}
|
|
576
638
|
|
|
577
639
|
#[must_use]
|
|
578
640
|
pub fn member(&self, str_id: &StringId) -> Option<&DeclarationId> {
|
|
579
|
-
all_namespaces!(self, it => it.member(str_id))
|
|
641
|
+
all_namespaces!(self, it => it.namespace_store.member(str_id))
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
pub fn add_member(&mut self, string_id: StringId, declaration_id: DeclarationId) {
|
|
645
|
+
all_namespaces!(self, it => it.namespace_store.add_member(string_id, declaration_id));
|
|
580
646
|
}
|
|
581
647
|
|
|
582
648
|
pub fn remove_member(&mut self, str_id: &StringId) -> Option<DeclarationId> {
|
|
583
|
-
all_namespaces!(self, it => it.remove_member(str_id))
|
|
649
|
+
all_namespaces!(self, it => it.namespace_store.remove_member(str_id))
|
|
584
650
|
}
|
|
585
651
|
|
|
586
652
|
#[must_use]
|
|
587
653
|
pub fn singleton_class(&self) -> Option<&DeclarationId> {
|
|
588
|
-
all_namespaces!(self, it => it.singleton_class_id())
|
|
654
|
+
all_namespaces!(self, it => it.namespace_store.singleton_class_id())
|
|
589
655
|
}
|
|
590
656
|
|
|
591
657
|
pub fn set_singleton_class_id(&mut self, declaration_id: DeclarationId) {
|
|
592
|
-
all_namespaces!(self, it => it.set_singleton_class_id(declaration_id));
|
|
658
|
+
all_namespaces!(self, it => it.namespace_store.set_singleton_class_id(declaration_id));
|
|
593
659
|
}
|
|
594
660
|
|
|
595
661
|
pub fn clear_singleton_class_id(&mut self) {
|
|
596
|
-
all_namespaces!(self, it => it.clear_singleton_class_id());
|
|
662
|
+
all_namespaces!(self, it => it.namespace_store.clear_singleton_class_id());
|
|
597
663
|
}
|
|
598
664
|
|
|
599
665
|
#[must_use]
|
|
600
666
|
pub fn owner_id(&self) -> &DeclarationId {
|
|
601
|
-
all_namespaces!(self, it => &it.owner_id)
|
|
667
|
+
all_namespaces!(self, it => &it.core.owner_id)
|
|
602
668
|
}
|
|
603
669
|
|
|
604
670
|
#[must_use]
|
|
605
671
|
pub fn name(&self) -> &str {
|
|
606
|
-
all_namespaces!(self, it => &it.name)
|
|
672
|
+
all_namespaces!(self, it => &it.core.name())
|
|
607
673
|
}
|
|
608
674
|
}
|
|
609
675
|
|
|
@@ -615,17 +681,23 @@ namespace_declaration!(SingletonClass, SingletonClassDeclaration);
|
|
|
615
681
|
assert_mem_size!(SingletonClassDeclaration, 184);
|
|
616
682
|
namespace_declaration!(Todo, TodoDeclaration);
|
|
617
683
|
assert_mem_size!(TodoDeclaration, 184);
|
|
618
|
-
|
|
684
|
+
|
|
685
|
+
pub type ConstantDeclaration = DeclarationCore<ConstantReferenceId>;
|
|
619
686
|
assert_mem_size!(ConstantDeclaration, 80);
|
|
620
|
-
|
|
687
|
+
|
|
688
|
+
pub type MethodDeclaration = DeclarationCore<MethodReferenceId>;
|
|
621
689
|
assert_mem_size!(MethodDeclaration, 80);
|
|
622
|
-
|
|
690
|
+
|
|
691
|
+
pub type GlobalVariableDeclaration = DeclarationCore<GlobalVariableReferenceId>;
|
|
623
692
|
assert_mem_size!(GlobalVariableDeclaration, 80);
|
|
624
|
-
|
|
693
|
+
|
|
694
|
+
pub type InstanceVariableDeclaration = DeclarationCore<InstanceVariableReferenceId>;
|
|
625
695
|
assert_mem_size!(InstanceVariableDeclaration, 80);
|
|
626
|
-
|
|
696
|
+
|
|
697
|
+
pub type ClassVariableDeclaration = DeclarationCore<ClassVariableReferenceId>;
|
|
627
698
|
assert_mem_size!(ClassVariableDeclaration, 80);
|
|
628
|
-
|
|
699
|
+
|
|
700
|
+
pub type ConstantAliasDeclaration = DeclarationCore<ConstantReferenceId>;
|
|
629
701
|
assert_mem_size!(ConstantAliasDeclaration, 80);
|
|
630
702
|
|
|
631
703
|
#[cfg(test)]
|
|
@@ -655,15 +727,15 @@ mod tests {
|
|
|
655
727
|
let member_name_id = StringId::from("Bar");
|
|
656
728
|
let member_decl_id = DeclarationId::from("Foo::Bar");
|
|
657
729
|
|
|
658
|
-
let Declaration::Namespace(
|
|
659
|
-
panic!("Expected a
|
|
730
|
+
let Declaration::Namespace(mut namespace) = decl else {
|
|
731
|
+
panic!("Expected a namespace declaration");
|
|
660
732
|
};
|
|
661
|
-
|
|
662
|
-
assert_eq!(
|
|
733
|
+
namespace.add_member(member_name_id, member_decl_id);
|
|
734
|
+
assert_eq!(namespace.members().len(), 1);
|
|
663
735
|
|
|
664
|
-
let removed =
|
|
736
|
+
let removed = namespace.remove_member(&member_name_id);
|
|
665
737
|
assert_eq!(removed, Some(member_decl_id));
|
|
666
|
-
assert_eq!(
|
|
738
|
+
assert_eq!(namespace.members().len(), 0);
|
|
667
739
|
}
|
|
668
740
|
|
|
669
741
|
#[test]
|