rubydex 0.2.4-aarch64-linux → 0.2.6-aarch64-linux

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -16
  3. data/THIRD_PARTY_LICENSES.html +6 -6
  4. data/exe/rubydex_mcp +17 -0
  5. data/ext/rubydex/definition.c +89 -2
  6. data/ext/rubydex/document.c +36 -0
  7. data/ext/rubydex/extconf.rb +8 -0
  8. data/ext/rubydex/graph.c +32 -18
  9. data/ext/rubydex/handle.h +21 -5
  10. data/lib/rubydex/3.2/rubydex.so +0 -0
  11. data/lib/rubydex/3.3/rubydex.so +0 -0
  12. data/lib/rubydex/3.4/rubydex.so +0 -0
  13. data/lib/rubydex/4.0/rubydex.so +0 -0
  14. data/lib/rubydex/bin/rubydex_mcp +0 -0
  15. data/lib/rubydex/declaration.rb +3 -3
  16. data/lib/rubydex/errors.rb +8 -0
  17. data/lib/rubydex/graph.rb +3 -1
  18. data/lib/rubydex/librubydex_sys.so +0 -0
  19. data/lib/rubydex/location.rb +24 -0
  20. data/lib/rubydex/version.rb +1 -1
  21. data/lib/rubydex.rb +1 -0
  22. data/rbi/rubydex.rbi +37 -14
  23. data/rust/Cargo.lock +3 -3
  24. data/rust/rubydex/Cargo.toml +7 -1
  25. data/rust/rubydex/src/dot.rs +609 -0
  26. data/rust/rubydex/src/indexing/local_graph.rs +38 -0
  27. data/rust/rubydex/src/indexing/rbs_indexer.rs +19 -1
  28. data/rust/rubydex/src/indexing/ruby_indexer.rs +10 -0
  29. data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +5 -1
  30. data/rust/rubydex/src/indexing.rs +38 -12
  31. data/rust/rubydex/src/lib.rs +2 -1
  32. data/rust/rubydex/src/listing.rs +14 -3
  33. data/rust/rubydex/src/main.rs +35 -7
  34. data/rust/rubydex/src/model/built_in.rs +5 -2
  35. data/rust/rubydex/src/model/comment.rs +2 -0
  36. data/rust/rubydex/src/model/declaration.rs +1 -0
  37. data/rust/rubydex/src/model/definitions.rs +20 -19
  38. data/rust/rubydex/src/model/document.rs +2 -0
  39. data/rust/rubydex/src/model/encoding.rs +2 -0
  40. data/rust/rubydex/src/model/graph.rs +51 -13
  41. data/rust/rubydex/src/model/identity_maps.rs +3 -0
  42. data/rust/rubydex/src/model/ids.rs +27 -1
  43. data/rust/rubydex/src/model/keywords.rs +3 -0
  44. data/rust/rubydex/src/model/name.rs +2 -0
  45. data/rust/rubydex/src/model/string_ref.rs +2 -0
  46. data/rust/rubydex/src/model/visibility.rs +3 -0
  47. data/rust/rubydex/src/operation/applier.rs +520 -0
  48. data/rust/rubydex/src/operation/mod.rs +285 -0
  49. data/rust/rubydex/src/operation/printer.rs +260 -0
  50. data/rust/rubydex/src/operation/ruby_builder.rs +2919 -0
  51. data/rust/rubydex/src/query.rs +114 -33
  52. data/rust/rubydex/src/resolution.rs +22 -9
  53. data/rust/rubydex/src/resolution_tests.rs +349 -209
  54. data/rust/rubydex/src/test_utils/graph_test.rs +19 -4
  55. data/rust/rubydex/src/test_utils/local_graph_test.rs +7 -6
  56. data/rust/rubydex/tests/cli.rs +17 -61
  57. data/rust/rubydex-mcp/Cargo.toml +9 -3
  58. data/rust/rubydex-mcp/src/server.rs +5 -1
  59. data/rust/rubydex-sys/Cargo.toml +9 -2
  60. data/rust/rubydex-sys/src/definition_api.rs +96 -2
  61. data/rust/rubydex-sys/src/document_api.rs +28 -0
  62. data/rust/rubydex-sys/src/graph_api.rs +2 -4
  63. metadata +11 -4
  64. data/rust/rubydex/src/visualization/dot.rs +0 -192
  65. data/rust/rubydex/src/visualization.rs +0 -6
@@ -2,6 +2,7 @@ use std::collections::HashSet;
2
2
  use std::collections::hash_map::Entry;
3
3
  use std::path::PathBuf;
4
4
 
5
+ use crate::assert_mem_size;
5
6
  use crate::diagnostic::Diagnostic;
6
7
  use crate::indexing::local_graph::LocalGraph;
7
8
  use crate::model::built_in::{OBJECT_ID, add_built_in_data};
@@ -28,6 +29,7 @@ pub enum NameDependent {
28
29
  /// This name's `nesting` is the key name — reference-only dependency.
29
30
  NestedName(NameId),
30
31
  }
32
+ assert_mem_size!(NameDependent, 16);
31
33
 
32
34
  /// Items processed by the unified invalidation worklist.
33
35
  enum InvalidationItem {
@@ -38,6 +40,7 @@ enum InvalidationItem {
38
40
  /// Ancestor context changed — unresolve references under this name but keep the name resolved.
39
41
  References(NameId),
40
42
  }
43
+ assert_mem_size!(InvalidationItem, 16);
41
44
 
42
45
  /// A work item produced by graph mutations (update/delete) that needs resolution.
43
46
  #[derive(Debug)]
@@ -49,6 +52,7 @@ pub enum Unit {
49
52
  /// A declaration whose ancestors need re-linearization
50
53
  Ancestors(DeclarationId),
51
54
  }
55
+ assert_mem_size!(Unit, 16);
52
56
 
53
57
  // The `Graph` is the global representation of the entire Ruby codebase. It contains all declarations and their
54
58
  // relationships
@@ -84,6 +88,7 @@ pub struct Graph {
84
88
  /// Paths to exclude from file discovery during indexing.
85
89
  excluded_paths: HashSet<PathBuf>,
86
90
  }
91
+ assert_mem_size!(Graph, 336);
87
92
 
88
93
  impl Graph {
89
94
  #[must_use]
@@ -306,9 +311,6 @@ impl Graph {
306
311
  self.definition_to_declaration_id(self.definitions.get(&definition_id).unwrap())
307
312
  }
308
313
 
309
- /// # Panics
310
- ///
311
- /// Panics if the definition is not found
312
314
  #[must_use]
313
315
  pub fn definition_to_declaration_id(&self, definition: &Definition) -> Option<&DeclarationId> {
314
316
  let (nesting_name_id, member_str_id) = match definition {
@@ -442,20 +444,21 @@ impl Graph {
442
444
  }
443
445
 
444
446
  /// Looks up the declaration for a `SelfReceiver` method/alias through the singleton class.
447
+ ///
448
+ /// Returns `None` when the owner cannot be resolved to a namespace with a singleton class. This
449
+ /// can happen when the enclosing construct resolved to a non-namespace declaration (e.g. a
450
+ /// constant or constant alias that a same-named `class`/`module` reopened without promotion), in
451
+ /// which case the method has no owning declaration.
445
452
  fn find_self_receiver_declaration(&self, def_id: DefinitionId, member_str_id: StringId) -> Option<&DeclarationId> {
446
453
  let owner_decl_id = self.definition_id_to_declaration_id(def_id)?;
447
454
  let singleton_id = self
448
455
  .declarations
449
- .get(owner_decl_id)
450
- .unwrap()
451
- .as_namespace()
452
- .unwrap()
456
+ .get(owner_decl_id)?
457
+ .as_namespace()?
453
458
  .singleton_class()?;
454
459
  self.declarations
455
- .get(singleton_id)
456
- .unwrap()
457
- .as_namespace()
458
- .unwrap()
460
+ .get(singleton_id)?
461
+ .as_namespace()?
459
462
  .member(&member_str_id)
460
463
  }
461
464
 
@@ -1540,8 +1543,8 @@ mod tests {
1540
1543
  use crate::model::declaration::Ancestors;
1541
1544
  use crate::test_utils::GraphTest;
1542
1545
  use crate::{
1543
- assert_declaration_does_not_exist, assert_dependents, assert_descendants, assert_members_eq,
1544
- assert_no_diagnostics, assert_no_members,
1546
+ assert_declaration_does_not_exist, assert_declaration_kind_eq, assert_dependents, assert_descendants,
1547
+ assert_members_eq, assert_no_diagnostics, assert_no_members,
1545
1548
  };
1546
1549
 
1547
1550
  #[test]
@@ -1563,6 +1566,41 @@ mod tests {
1563
1566
  );
1564
1567
  }
1565
1568
 
1569
+ #[test]
1570
+ fn singleton_method_in_non_namespace_owner_does_not_panic() {
1571
+ // `Aliased = Bar` assigns a constant to another constant, producing a (non-promotable)
1572
+ // `ConstantAlias` declaration. Reopening it with `class Aliased` is valid Ruby (it reopens
1573
+ // `Bar`), but the class definition is attached to the existing `ConstantAlias` declaration
1574
+ // without promoting it to a namespace. A `def self.foo` inside then has a `SelfReceiver`
1575
+ // owner whose declaration is not a namespace. Resolving that definition to its declaration
1576
+ // must return `None` rather than panicking.
1577
+ let mut context = GraphTest::new();
1578
+
1579
+ context.index_uri(
1580
+ "file:///foo.rb",
1581
+ "
1582
+ class Bar
1583
+ end
1584
+
1585
+ Aliased = Bar
1586
+
1587
+ class Aliased
1588
+ def self.foo; end
1589
+ end
1590
+ ",
1591
+ );
1592
+ context.resolve();
1593
+
1594
+ // The declaration stays a non-namespace constant alias.
1595
+ assert_declaration_kind_eq!(context, "Aliased", "ConstantAlias");
1596
+
1597
+ // Mirrors what consumers like the DOT exporter do: resolve every definition to its
1598
+ // declaration. This previously panicked on the singleton method's non-namespace owner.
1599
+ for definition in context.graph().definitions().values() {
1600
+ let _ = context.graph().definition_to_declaration_id(definition);
1601
+ }
1602
+ }
1603
+
1566
1604
  #[test]
1567
1605
  fn deleting_file_triggers_name_dependent_cleanup() {
1568
1606
  let mut context = GraphTest::new();
@@ -6,10 +6,13 @@ use std::{
6
6
  hash::{BuildHasher, Hasher},
7
7
  };
8
8
 
9
+ use crate::assert_mem_size;
10
+
9
11
  #[derive(Default)]
10
12
  pub struct IdentityHasher {
11
13
  hash: u64,
12
14
  }
15
+ assert_mem_size!(IdentityHasher, 8);
13
16
 
14
17
  impl Hasher for IdentityHasher {
15
18
  fn write(&mut self, _bytes: &[u8]) {
@@ -1,4 +1,8 @@
1
- use crate::{assert_mem_size, model::id::Id};
1
+ use crate::{
2
+ assert_mem_size,
3
+ model::{definitions::Receiver, id::Id},
4
+ offset::Offset,
5
+ };
2
6
 
3
7
  #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
4
8
  pub struct DeclarationMarker;
@@ -12,6 +16,28 @@ pub struct DefinitionMarker;
12
16
  pub type DefinitionId = Id<DefinitionMarker>;
13
17
  assert_mem_size!(DefinitionId, 8);
14
18
 
19
+ #[must_use]
20
+ pub fn namespace_definition_id(uri_id: UriId, offset: &Offset, name_id: NameId) -> DefinitionId {
21
+ DefinitionId::from(&format!("{}{}{}", *uri_id, offset.start(), *name_id))
22
+ }
23
+
24
+ #[must_use]
25
+ pub fn method_definition_id(
26
+ uri_id: UriId,
27
+ offset: &Offset,
28
+ str_id: StringId,
29
+ receiver: Option<&Receiver>,
30
+ ) -> DefinitionId {
31
+ let mut formatted_id = format!("{}{}{}", *uri_id, offset.start(), *str_id);
32
+ if let Some(receiver) = receiver {
33
+ match receiver {
34
+ Receiver::SelfReceiver(def_id) => formatted_id.push_str(&def_id.to_string()),
35
+ Receiver::ConstantReceiver(name_id) => formatted_id.push_str(&name_id.to_string()),
36
+ }
37
+ }
38
+ DefinitionId::from(&formatted_id)
39
+ }
40
+
15
41
  #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)]
16
42
  pub struct UriMarker;
17
43
  // UriId represents the ID of a URI, which is the unique identifier for a document
@@ -1,3 +1,5 @@
1
+ use crate::assert_mem_size;
2
+
1
3
  /// A Ruby keyword with its documentation.
2
4
  #[derive(Debug)]
3
5
  pub struct Keyword {
@@ -6,6 +8,7 @@ pub struct Keyword {
6
8
  /// Documentation string for hover display
7
9
  documentation: &'static str,
8
10
  }
11
+ assert_mem_size!(Keyword, 32);
9
12
 
10
13
  impl Keyword {
11
14
  #[must_use]
@@ -141,6 +141,7 @@ pub struct ResolvedName {
141
141
  name: Name,
142
142
  declaration_id: DeclarationId,
143
143
  }
144
+ assert_mem_size!(ResolvedName, 48);
144
145
 
145
146
  impl ResolvedName {
146
147
  #[must_use]
@@ -173,6 +174,7 @@ pub enum NameRef {
173
174
  /// This name has been resolved to an existing declaration
174
175
  Resolved(Box<ResolvedName>),
175
176
  }
177
+ assert_mem_size!(NameRef, 16);
176
178
 
177
179
  impl NameRef {
178
180
  #[must_use]
@@ -1,3 +1,4 @@
1
+ use crate::assert_mem_size;
1
2
  use std::ops::Deref;
2
3
 
3
4
  /// A reference-counted string used in the graph.
@@ -11,6 +12,7 @@ pub struct StringRef {
11
12
  value: String,
12
13
  ref_count: u32,
13
14
  }
15
+ assert_mem_size!(StringRef, 32);
14
16
 
15
17
  impl StringRef {
16
18
  #[must_use]
@@ -1,6 +1,8 @@
1
1
  use core::fmt;
2
2
  use std::fmt::Display;
3
3
 
4
+ use crate::assert_mem_size;
5
+
4
6
  #[derive(Debug, Clone, Copy, PartialEq, Eq)]
5
7
  pub enum Visibility {
6
8
  Public,
@@ -8,6 +10,7 @@ pub enum Visibility {
8
10
  Private,
9
11
  ModuleFunction,
10
12
  }
13
+ assert_mem_size!(Visibility, 1);
11
14
 
12
15
  impl Visibility {
13
16
  /// Parse a visibility from a string.