rubydex 0.2.5 → 0.2.6

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -16
  3. data/THIRD_PARTY_LICENSES.html +6 -6
  4. data/ext/rubydex/definition.c +33 -2
  5. data/ext/rubydex/document.c +36 -0
  6. data/ext/rubydex/graph.c +32 -18
  7. data/ext/rubydex/handle.h +21 -5
  8. data/lib/rubydex/bin/rubydex_mcp.exe +0 -0
  9. data/lib/rubydex/errors.rb +8 -0
  10. data/lib/rubydex/location.rb +24 -0
  11. data/lib/rubydex/version.rb +1 -1
  12. data/lib/rubydex.rb +1 -0
  13. data/rbi/rubydex.rbi +29 -12
  14. data/rust/Cargo.lock +3 -3
  15. data/rust/rubydex/Cargo.toml +7 -1
  16. data/rust/rubydex/src/dot.rs +609 -0
  17. data/rust/rubydex/src/indexing/rbs_indexer.rs +19 -1
  18. data/rust/rubydex/src/indexing/ruby_indexer.rs +4 -0
  19. data/rust/rubydex/src/lib.rs +1 -1
  20. data/rust/rubydex/src/main.rs +8 -5
  21. data/rust/rubydex/src/model/built_in.rs +5 -2
  22. data/rust/rubydex/src/model/comment.rs +2 -0
  23. data/rust/rubydex/src/model/declaration.rs +1 -0
  24. data/rust/rubydex/src/model/definitions.rs +13 -1
  25. data/rust/rubydex/src/model/document.rs +2 -0
  26. data/rust/rubydex/src/model/encoding.rs +2 -0
  27. data/rust/rubydex/src/model/graph.rs +51 -13
  28. data/rust/rubydex/src/model/identity_maps.rs +3 -0
  29. data/rust/rubydex/src/model/keywords.rs +3 -0
  30. data/rust/rubydex/src/model/name.rs +2 -0
  31. data/rust/rubydex/src/model/string_ref.rs +2 -0
  32. data/rust/rubydex/src/model/visibility.rs +3 -0
  33. data/rust/rubydex/src/operation/applier.rs +1 -0
  34. data/rust/rubydex/src/operation/mod.rs +1 -0
  35. data/rust/rubydex/src/operation/ruby_builder.rs +4 -0
  36. data/rust/rubydex/src/query.rs +114 -33
  37. data/rust/rubydex/src/resolution.rs +16 -8
  38. data/rust/rubydex/src/resolution_tests.rs +132 -0
  39. data/rust/rubydex/tests/cli.rs +17 -61
  40. data/rust/rubydex-mcp/Cargo.toml +9 -3
  41. data/rust/rubydex-sys/Cargo.toml +9 -2
  42. data/rust/rubydex-sys/src/definition_api.rs +72 -2
  43. data/rust/rubydex-sys/src/document_api.rs +28 -0
  44. data/rust/rubydex-sys/src/graph_api.rs +1 -3
  45. metadata +4 -4
  46. data/rust/rubydex/src/visualization/dot.rs +0 -192
  47. data/rust/rubydex/src/visualization.rs +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8d3ab0270eef0ad7036990b31d888f5d861e7f261b37f76ba3bf99cd1d0b426a
4
- data.tar.gz: 59c5a86dbce3070f7e7d8373b9d4c195ad6d282bb78339395318ca06c39d0bb6
3
+ metadata.gz: c776445f3a3589b62c6f4e1987d424f91aa020585434182c4d16087097e28fb1
4
+ data.tar.gz: 4d5e1862670c7dd767bce180f70dda589237bf9696b82c99d971b58f2b6ec9bb
5
5
  SHA512:
6
- metadata.gz: 43d479ff7d5bbae33645d8ebbd06c63b17d508a7b87239dec3c07b2987d54ab1ea5578a20d0e310f9f6bd357e95cf731b623d8f0a40d5fa8472eba1dbb1039ec
7
- data.tar.gz: cd85f8985773424f7233b9d5e83d4efc452786a1b1232720942f4c430c4b1e12226a7da72fd88ea3f1dd92587bf8db814f8447dd15cc4bf5d43f56892d485705
6
+ metadata.gz: 82cc3034740d1e985a938492228a72b77fb4ea3687e07d87ec0cabfb3c342f26db21cc93f1559879037a45ab1d9eed0bb0869c64f55d6ec16ecd50226a5177a8
7
+ data.tar.gz: e8f7f5ef9e65ab9bbb82fa4cb1f69db91d8df4204ce008beef5f529b18b929a5b4c383ce4083d90fb05a9e054c35e6d04ca58d4b911f2db2e29a7c9c5a6e4698
data/README.md CHANGED
@@ -84,30 +84,31 @@ like Claude to semantically query your Ruby codebase.
84
84
 
85
85
  ### Setup
86
86
 
87
- 1. Install the binary:
87
+ 1. Add Rubydex to the Ruby project you want to index:
88
+ ```ruby
89
+ gem "rubydex"
90
+ ```
91
+
92
+ 2. Install the bundle:
88
93
  ```bash
89
- cargo install --path rust/rubydex-mcp
94
+ bundle install
90
95
  ```
91
96
 
92
- 2. Add rubydex to the Ruby project you want to index:
97
+ 3. Configure your MCP client to run `bundle exec rubydex_mcp`.
98
+
99
+ Using Claude Code as an example:
93
100
  ```bash
94
- claude mcp add --scope project rubydex "\${HOME}/.cargo/bin/rubydex_mcp"
101
+ claude mcp add --scope project rubydex -- bundle exec rubydex_mcp
95
102
  ```
96
103
 
97
- Or manually create a `.mcp.json` in the project root:
98
- ```json
99
- {
100
- "mcpServers": {
101
- "rubydex": {
102
- "command": "${HOME}/.cargo/bin/rubydex_mcp"
103
- }
104
- }
105
- }
104
+ Using Codex as an example:
105
+ ```bash
106
+ codex mcp add rubydex -- bundle exec rubydex_mcp
106
107
  ```
107
108
 
108
- 3. Start Claude Code from that project directory. The MCP server indexes
109
- the project at startup and provides semantic code intelligence tools.
110
- Verify with `/mcp` in the session.
109
+ Start your MCP client from that project directory. The MCP server indexes
110
+ the project at startup and provides semantic code intelligence tools through
111
+ the tools below.
111
112
 
112
113
  ### Available MCP Tools
113
114
 
@@ -3823,14 +3823,14 @@ SOFTWARE.
3823
3823
  <h4>Used by:</h4>
3824
3824
  <ul class="license-used-by">
3825
3825
  <li><a
3826
- href=" https://crates.io/crates/rubydex ">rubydex
3827
- 0.1.0</a></li>
3826
+ href=" https://github.com/Shopify/rubydex ">rubydex
3827
+ 0.2.6</a></li>
3828
3828
  <li><a
3829
- href=" https://crates.io/crates/rubydex-mcp ">rubydex-mcp
3830
- 0.1.0</a></li>
3829
+ href=" https://github.com/Shopify/rubydex ">rubydex-mcp
3830
+ 0.2.6</a></li>
3831
3831
  <li><a
3832
- href=" https://crates.io/crates/rubydex-sys ">rubydex-sys
3833
- 0.1.0</a></li>
3832
+ href=" https://github.com/Shopify/rubydex ">rubydex-sys
3833
+ 0.2.6</a></li>
3834
3834
  <li><a
3835
3835
  href=" https://github.com/DimaKudosh/difflib ">difflib
3836
3836
  0.4.0</a></li>
@@ -154,8 +154,8 @@ static VALUE rdxr_definition_deprecated(VALUE self) {
154
154
  }
155
155
 
156
156
  // Definition#name_location -> Rubydex::Location or nil
157
- // For class, module, and singleton class definitions, returns the location of just the name
158
- // (e.g., "Bar" in "class Foo::Bar"). For other definition types, returns nil.
157
+ // For class, module, singleton class, and method definitions, returns the location of just the name
158
+ // (e.g., "Bar" in "class Foo::Bar", or "foo" in "def foo"). For other definition types, returns nil.
159
159
  static VALUE rdxr_definition_name_location(VALUE self) {
160
160
  HandleData *data;
161
161
  TypedData_Get_Struct(self, HandleData, &handle_type, data);
@@ -341,6 +341,36 @@ static VALUE rdxr_method_alias_definition_signatures(VALUE self) {
341
341
  return rdxi_signatures_to_ruby(arr);
342
342
  }
343
343
 
344
+ // MethodAliasDefinition#target -> Rubydex::Method?
345
+ // Returns the resolved target method declaration by following the alias chain, or nil if the chain could not be
346
+ // resolved (the target name doesn't exist on the owner, or the owner itself never resolved). Raises
347
+ // Rubydex::AliasCycleError when the alias chain forms a cycle.
348
+ static VALUE rdxr_method_alias_definition_target(VALUE self) {
349
+ HandleData *data;
350
+ TypedData_Get_Struct(self, HandleData, &handle_type, data);
351
+
352
+ void *graph;
353
+ TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
354
+
355
+ CMethodAliasTargetResult result = rdx_method_alias_definition_target(graph, data->id);
356
+
357
+ switch (result.status) {
358
+ case CMethodAliasResolution_Resolved: {
359
+ VALUE decl_class = rdxi_declaration_class_for_kind(result.declaration->kind);
360
+ VALUE argv[] = {data->graph_obj, ULL2NUM(result.declaration->id)};
361
+
362
+ free_c_declaration(result.declaration);
363
+ return rb_class_new_instance(2, argv, decl_class);
364
+ }
365
+ case CMethodAliasResolution_NotFound:
366
+ return Qnil;
367
+ case CMethodAliasResolution_Cycle:
368
+ rb_raise(rb_const_get(mRubydex, rb_intern("AliasCycleError")), "method alias chain forms a cycle");
369
+ default:
370
+ rb_raise(rb_eRuntimeError, "Unknown CMethodAliasResolution: %d", result.status);
371
+ }
372
+ }
373
+
344
374
  void rdxi_initialize_definition(VALUE mod) {
345
375
  mRubydex = mod;
346
376
 
@@ -387,5 +417,6 @@ void rdxi_initialize_definition(VALUE mod) {
387
417
  cClassVariableDefinition = rb_define_class_under(mRubydex, "ClassVariableDefinition", cDefinition);
388
418
  cMethodAliasDefinition = rb_define_class_under(mRubydex, "MethodAliasDefinition", cDefinition);
389
419
  rb_define_method(cMethodAliasDefinition, "signatures", rdxr_method_alias_definition_signatures, 0);
420
+ rb_define_method(cMethodAliasDefinition, "target", rdxr_method_alias_definition_target, 0);
390
421
  cGlobalVariableAliasDefinition = rb_define_class_under(mRubydex, "GlobalVariableAliasDefinition", cDefinition);
391
422
  }
@@ -3,6 +3,7 @@
3
3
  #include "graph.h"
4
4
  #include "handle.h"
5
5
  #include "rustbindings.h"
6
+ #include "utils.h"
6
7
 
7
8
  VALUE cDocument;
8
9
 
@@ -85,6 +86,40 @@ static VALUE rdxr_document_definitions(VALUE self) {
85
86
  return self;
86
87
  }
87
88
 
89
+ // Size function for the Document#method_references enumerator
90
+ static VALUE document_method_references_size(VALUE self, VALUE _args, VALUE _eobj) {
91
+ HandleData *data;
92
+ TypedData_Get_Struct(self, HandleData, &handle_type, data);
93
+
94
+ void *graph;
95
+ TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
96
+ struct MethodReferencesIter *iter = rdx_document_method_references_iter_new(graph, data->id);
97
+ size_t len = rdx_method_references_iter_len(iter);
98
+ rdx_method_references_iter_free(iter);
99
+
100
+ return SIZET2NUM(len);
101
+ }
102
+
103
+ // Document#method_references: () -> Enumerator[MethodReference]
104
+ // Returns an enumerator that yields all method references for this document lazily
105
+ static VALUE rdxr_document_method_references(VALUE self) {
106
+ if (!rb_block_given_p()) {
107
+ return rb_enumeratorize_with_size(self, rb_str_new2("method_references"), 0, NULL,
108
+ document_method_references_size);
109
+ }
110
+
111
+ HandleData *data;
112
+ TypedData_Get_Struct(self, HandleData, &handle_type, data);
113
+
114
+ void *graph;
115
+ TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
116
+ void *iter = rdx_document_method_references_iter_new(graph, data->id);
117
+ VALUE args = rb_ary_new_from_args(2, data->graph_obj, ULL2NUM((uintptr_t)iter));
118
+ rb_ensure(rdxi_method_references_yield, args, rdxi_method_references_ensure, args);
119
+
120
+ return self;
121
+ }
122
+
88
123
  void rdxi_initialize_document(VALUE mRubydex) {
89
124
  cDocument = rb_define_class_under(mRubydex, "Document", rb_cObject);
90
125
 
@@ -92,6 +127,7 @@ void rdxi_initialize_document(VALUE mRubydex) {
92
127
  rb_define_method(cDocument, "initialize", rdxr_handle_initialize, 2);
93
128
  rb_define_method(cDocument, "uri", rdxr_document_uri, 0);
94
129
  rb_define_method(cDocument, "definitions", rdxr_document_definitions, 0);
130
+ rb_define_method(cDocument, "method_references", rdxr_document_method_references, 0);
95
131
 
96
132
  rb_funcall(rb_singleton_class(cDocument), rb_intern("private"), 1, ID2SYM(rb_intern("new")));
97
133
  }
data/ext/rubydex/graph.c CHANGED
@@ -16,17 +16,20 @@ static VALUE cKeywordParameter;
16
16
  // Interned once in `rdxi_initialize_graph` to avoid repeated symbol-table lookups on hot completion paths.
17
17
  static ID id_self_receiver;
18
18
 
19
- // Extracts the optional `self_receiver:` kwarg from `opts`. Returns NULL when the kwarg is
20
- // absent or nil; raises ArgumentError when the value is the wrong type or empty.
19
+ // Extracts the required `self_receiver:` kwarg from `opts`. Returns NULL when the value is `nil`,
20
+ // which means "no self-type to walk" (e.g., empty class body where the singleton class hasn't
21
+ // been created). Raises ArgumentError if the kwarg is absent, of the wrong type, or an empty
22
+ // string. The kwarg is required so that callers commit to a self type — there is no implicit
23
+ // default.
21
24
  static const char *extract_self_receiver(VALUE opts) {
22
25
  if (NIL_P(opts)) {
23
- return NULL;
26
+ rb_raise(rb_eArgError, "missing keyword: self_receiver");
24
27
  }
25
28
 
26
29
  VALUE kwarg_val;
27
- rb_get_kwargs(opts, &id_self_receiver, 0, 1, &kwarg_val);
30
+ rb_get_kwargs(opts, &id_self_receiver, 1, 0, &kwarg_val);
28
31
 
29
- if (kwarg_val == Qundef || NIL_P(kwarg_val)) {
32
+ if (NIL_P(kwarg_val)) {
30
33
  return NULL;
31
34
  }
32
35
 
@@ -45,7 +48,18 @@ static void graph_free(void *ptr) {
45
48
  }
46
49
  }
47
50
 
48
- const rb_data_type_t graph_type = {"Graph", {0, graph_free, 0}, 0, 0, RUBY_TYPED_FREE_IMMEDIATELY};
51
+ const rb_data_type_t graph_type = {
52
+ .wrap_struct_name = "Graph",
53
+ .function = {
54
+ .dmark = NULL,
55
+ .dfree = graph_free,
56
+ .dsize = NULL,
57
+ .dcompact = NULL,
58
+ },
59
+ .parent = NULL,
60
+ .data = NULL,
61
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
62
+ };
49
63
 
50
64
  // Custom allocator for the Graph class. Calls into Rust to create a new `Arc<Mutex<Graph>>` that gets stored internally
51
65
  // as a void pointer
@@ -589,11 +603,10 @@ static VALUE completion_result_to_ruby_array(struct CompletionResult result, VAL
589
603
  return ruby_array;
590
604
  }
591
605
 
592
- // Graph#complete_expression: (Array[String] nesting, self_receiver: nil) -> Array[Declaration | Keyword]
606
+ // Graph#complete_expression: (Array[String] nesting, self_receiver:) -> Array[Declaration | Keyword]
593
607
  // Returns completion candidates for an expression context.
594
- // The nesting array represents the lexical scope stack. The optional self_receiver keyword argument
595
- // overrides the self-type (e.g., "Foo::<Foo>" for `def Foo.bar`); when nil, self is derived from
596
- // the innermost nesting element.
608
+ // The nesting array represents the lexical scope stack. The required self_receiver keyword argument overrides the
609
+ // self-type (e.g., "Foo::<Foo>" for `def Foo.bar`); when nil, self is derived from the innermost nesting element.
597
610
  static VALUE rdxr_graph_complete_expression(int argc, VALUE *argv, VALUE self) {
598
611
  VALUE nesting, opts;
599
612
  rb_scan_args(argc, argv, "1:", &nesting, &opts);
@@ -614,10 +627,11 @@ static VALUE rdxr_graph_complete_expression(int argc, VALUE *argv, VALUE self) {
614
627
  return completion_result_to_ruby_array(result, self);
615
628
  }
616
629
 
617
- // Graph#complete_namespace_access: (String name, self_receiver: nil) -> Array[Declaration]
630
+ // Graph#complete_namespace_access: (String name, self_receiver:) -> Array[Declaration]
618
631
  // Returns completion candidates after a namespace access operator (e.g., `Foo::`).
619
- // The optional self_receiver kwarg is the caller's runtime self type, used to filter
620
- // visibility-restricted singleton methods (e.g., `private_class_method`).
632
+ // The required self_receiver kwarg is the caller's runtime self type, used to filter
633
+ // visibility-restricted singleton methods (e.g., `private_class_method`). Pass `nil` when there
634
+ // is no caller context.
621
635
  static VALUE rdxr_graph_complete_namespace_access(int argc, VALUE *argv, VALUE self) {
622
636
  VALUE name, opts;
623
637
  rb_scan_args(argc, argv, "1:", &name, &opts);
@@ -633,10 +647,10 @@ static VALUE rdxr_graph_complete_namespace_access(int argc, VALUE *argv, VALUE s
633
647
  return completion_result_to_ruby_array(result, self);
634
648
  }
635
649
 
636
- // Graph#complete_method_call: (String name, self_receiver: nil) -> Array[Declaration]
650
+ // Graph#complete_method_call: (String name, self_receiver:) -> Array[Declaration]
637
651
  // Returns completion candidates after a method call operator (e.g., `foo.`).
638
- // The optional self_receiver kwarg is the caller's runtime self type, used for MRI-style
639
- // visibility checks (private/protected).
652
+ // The required self_receiver kwarg is the caller's runtime self type, used for visibility checks (private/protected).
653
+ // Pass `nil` when there is no caller context.
640
654
  static VALUE rdxr_graph_complete_method_call(int argc, VALUE *argv, VALUE self) {
641
655
  VALUE name, opts;
642
656
  rb_scan_args(argc, argv, "1:", &name, &opts);
@@ -652,9 +666,9 @@ static VALUE rdxr_graph_complete_method_call(int argc, VALUE *argv, VALUE self)
652
666
  return completion_result_to_ruby_array(result, self);
653
667
  }
654
668
 
655
- // Graph#complete_method_argument: (String name, Array[String] nesting, self_receiver: nil) -> Array[Declaration | Keyword | KeywordParameter]
669
+ // Graph#complete_method_argument: (String name, Array[String] nesting, self_receiver:) -> Array[Declaration | Keyword | KeywordParameter]
656
670
  // Returns completion candidates inside a method call's argument list (e.g., `foo.bar(|)`).
657
- // See complete_expression for semantics of self_receiver.
671
+ // See complete_expression for semantics of self_receiver (required, may be nil).
658
672
  static VALUE rdxr_graph_complete_method_argument(int argc, VALUE *argv, VALUE self) {
659
673
  VALUE name, nesting, opts;
660
674
  rb_scan_args(argc, argv, "2:", &name, &nesting, &opts);
data/ext/rubydex/handle.h CHANGED
@@ -22,12 +22,25 @@ static void handle_free(void *ptr) {
22
22
  }
23
23
 
24
24
  static const rb_data_type_t handle_type = {
25
- "RubydexHandle", {handle_mark, handle_free, 0}, 0, 0, RUBY_TYPED_FREE_IMMEDIATELY};
25
+ .wrap_struct_name = "RubydexHandle",
26
+ .function = {
27
+ .dmark = handle_mark,
28
+ .dfree = handle_free,
29
+ .dsize = NULL,
30
+ .dcompact = NULL,
31
+ },
32
+ .parent = NULL,
33
+ .data = NULL,
34
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
35
+ };
26
36
 
27
37
  static VALUE rdxr_handle_alloc(VALUE klass) {
28
38
  HandleData *data = ALLOC(HandleData);
29
- data->graph_obj = Qnil;
30
- data->id = 0;
39
+
40
+ *data = (HandleData) {
41
+ .graph_obj = Qnil,
42
+ .id = 0,
43
+ };
31
44
 
32
45
  return TypedData_Wrap_Struct(klass, &handle_type, data);
33
46
  }
@@ -35,8 +48,11 @@ static VALUE rdxr_handle_alloc(VALUE klass) {
35
48
  static VALUE rdxr_handle_initialize(VALUE self, VALUE graph_obj, VALUE id_val) {
36
49
  HandleData *data;
37
50
  TypedData_Get_Struct(self, HandleData, &handle_type, data);
38
- data->graph_obj = graph_obj;
39
- data->id = NUM2ULL(id_val);
51
+
52
+ *data = (HandleData) {
53
+ .graph_obj = graph_obj,
54
+ .id = NUM2ULL(id_val),
55
+ };
40
56
 
41
57
  return self;
42
58
  }
Binary file
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubydex
4
+ class Error < StandardError; end
5
+
6
+ # Raised when `MethodAliasDefinition#target` walks an alias chain that loops back on itself.
7
+ class AliasCycleError < Error; end
8
+ end
@@ -14,6 +14,19 @@ module Rubydex
14
14
  #: Integer
15
15
  attr_reader :start_line, :end_line, :start_column, :end_column
16
16
 
17
+ class << self
18
+ #: (Prism::Location prism_location, uri: String) -> Location
19
+ def from_prism(prism_location, uri:)
20
+ Location.new(
21
+ uri: uri,
22
+ start_line: prism_location.start_line - 1,
23
+ start_column: prism_location.start_column,
24
+ end_line: prism_location.end_line - 1,
25
+ end_column: prism_location.end_column,
26
+ )
27
+ end
28
+ end
29
+
17
30
  #: (?uri: String, ?start_line: Integer, ?end_line: Integer, ?start_column: Integer, ?end_column: Integer) -> void
18
31
  def initialize(uri:, start_line:, end_line:, start_column:, end_column:)
19
32
  @uri = uri
@@ -68,6 +81,17 @@ module Rubydex
68
81
  # A one based location intended for display purposes. This is what should be used when displaying a location to users,
69
82
  # like in CLIs
70
83
  class DisplayLocation < Location
84
+ class << self
85
+ #: (Prism::Location prism_location, uri: String) -> Location
86
+ def from_prism(prism_location, uri:)
87
+ raise NotImplementedError, <<~MESSAGE
88
+ Cannot convert Prism::Location directly to a Rubydex::DisplayLocation.
89
+ Start with `Rubydex::Location.from_prism(...)` and then convert the resulting
90
+ location with `to_display`
91
+ MESSAGE
92
+ end
93
+ end
94
+
71
95
  # Returns itself
72
96
  #
73
97
  #: () -> DisplayLocation
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rubydex
4
- VERSION = "0.2.5"
4
+ VERSION = "0.2.6"
5
5
  end
data/lib/rubydex.rb CHANGED
@@ -14,6 +14,7 @@ rescue LoadError
14
14
  require "rubydex/rubydex"
15
15
  end
16
16
 
17
+ require "rubydex/errors"
17
18
  require "rubydex/failures"
18
19
  require "rubydex/location"
19
20
  require "rubydex/comment"
data/rbi/rubydex.rbi CHANGED
@@ -174,7 +174,10 @@ class Rubydex::ConstantDefinition < Rubydex::Definition; end
174
174
  class Rubydex::GlobalVariableAliasDefinition < Rubydex::Definition; end
175
175
  class Rubydex::GlobalVariableDefinition < Rubydex::Definition; end
176
176
  class Rubydex::InstanceVariableDefinition < Rubydex::Definition; end
177
- class Rubydex::MethodAliasDefinition < Rubydex::Definition; end
177
+ class Rubydex::MethodAliasDefinition < Rubydex::Definition
178
+ sig { returns(T.nilable(Rubydex::Method)) }
179
+ def target; end
180
+ end
178
181
  class Rubydex::MethodDefinition < Rubydex::Definition; end
179
182
 
180
183
  class Rubydex::ModuleDefinition < Rubydex::Definition
@@ -246,6 +249,9 @@ class Rubydex::Document
246
249
  sig { returns(T::Enumerable[Rubydex::Definition]) }
247
250
  def definitions; end
248
251
 
252
+ sig { returns(T::Enumerable[Rubydex::MethodReference]) }
253
+ def method_references; end
254
+
249
255
  sig { returns(String) }
250
256
  def uri; end
251
257
 
@@ -257,6 +263,7 @@ class Rubydex::Document
257
263
  end
258
264
 
259
265
  class Rubydex::Error < StandardError; end
266
+ class Rubydex::AliasCycleError < Rubydex::Error; end
260
267
 
261
268
  class Rubydex::Failure
262
269
  sig { params(message: String).void }
@@ -344,48 +351,48 @@ class Rubydex::Graph
344
351
  # Returns completion candidates for an expression context. This includes all keywords, constants, methods, instance
345
352
  # variables, class variables and global variables reachable from the current lexical scope and self type.
346
353
  #
347
- # The nesting array represents the lexical scope stack. The optional `self_receiver` keyword argument overrides the
354
+ # The nesting array represents the lexical scope stack. The required `self_receiver` keyword argument overrides the
348
355
  # self type independently of the lexical scope (e.g., `"Foo::<Foo>"` for `def Foo.bar`). This distinction is important
349
356
  # because constants and class variables are always attached to the lexical scope. Meanwhile, methods and instance
350
- # variables are attached to the type of `self` and those don't always match.
357
+ # variables are attached to the type of `self` and those don't always match. Pass `nil` when the self type is unknown
351
358
  sig do
352
359
  params(
353
360
  nesting: T::Array[String],
354
361
  self_receiver: T.nilable(String),
355
362
  ).returns(T::Array[T.any(Rubydex::Declaration, Rubydex::Keyword)])
356
363
  end
357
- def complete_expression(nesting, self_receiver: nil); end
364
+ def complete_expression(nesting, self_receiver:); end
358
365
 
359
366
  # Returns completion candidates after a namespace access operator (e.g., `Foo::`). This includes all constants and
360
367
  # singleton methods for the namespace and its ancestors.
361
368
  #
362
- # The optional `self_receiver` kwarg is the caller's runtime self type. It's used to filter visibility-restricted
363
- # singleton methods (e.g., `private_class_method`). Pass `nil` (the default) for top-level/script scope.
369
+ # The required `self_receiver` kwarg is the caller's runtime self type. It's used to filter visibility-restricted
370
+ # singleton methods (e.g., `private_class_method`). Pass `nil` for top-level/script scope.
364
371
  sig do
365
372
  params(
366
373
  name: String,
367
374
  self_receiver: T.nilable(String),
368
375
  ).returns(T::Array[Rubydex::Declaration])
369
376
  end
370
- def complete_namespace_access(name, self_receiver: nil); end
377
+ def complete_namespace_access(name, self_receiver:); end
371
378
 
372
379
  # Returns completion candidates after a method call operator (e.g., `foo.`). This includes all methods that exist on
373
380
  # the type of the receiver and its ancestors.
374
381
  #
375
- # The optional `self_receiver` kwarg is the caller's runtime self type. It's used for visibility checks for `private`
376
- # and `protected` methods. Pass `nil` (the default) for top-level/script scope.
382
+ # The required `self_receiver` kwarg is the caller's runtime self type. It's used for visibility checks for `private`
383
+ # and `protected` methods. Pass `nil` for top-level/script scope.
377
384
  sig do
378
385
  params(
379
386
  name: String,
380
387
  self_receiver: T.nilable(String),
381
388
  ).returns(T::Array[Rubydex::Method])
382
389
  end
383
- def complete_method_call(name, self_receiver: nil); end
390
+ def complete_method_call(name, self_receiver:); end
384
391
 
385
392
  # Returns completion candidates inside a method call's argument list (e.g., `foo.bar(|)`). This includes everything
386
393
  # that expression completion provides plus keyword argument names of the method being called.
387
394
  #
388
- # See `complete_expression` for the semantics of `nesting` and `self_receiver`.
395
+ # See `complete_expression` for the semantics of `nesting` and `self_receiver` (required, may be `nil`).
389
396
  sig do
390
397
  params(
391
398
  name: String,
@@ -393,7 +400,7 @@ class Rubydex::Graph
393
400
  self_receiver: T.nilable(String),
394
401
  ).returns(T::Array[T.any(Rubydex::Declaration, Rubydex::Keyword, Rubydex::KeywordParameter)])
395
402
  end
396
- def complete_method_argument(name, nesting, self_receiver: nil); end
403
+ def complete_method_argument(name, nesting, self_receiver:); end
397
404
 
398
405
  private
399
406
 
@@ -411,6 +418,11 @@ class Rubydex::Graph
411
418
  end
412
419
 
413
420
  class Rubydex::DisplayLocation < Rubydex::Location
421
+ class << self
422
+ sig { params(prism_location: Prism::Location, uri: String).returns(T.noreturn) }
423
+ def from_prism(prism_location, uri:); end
424
+ end
425
+
414
426
  sig { returns([String, Integer, Integer, Integer, Integer]) }
415
427
  def comparable_values; end
416
428
 
@@ -424,6 +436,11 @@ end
424
436
  class Rubydex::Location
425
437
  include ::Comparable
426
438
 
439
+ class << self
440
+ sig { params(prism_location: Prism::Location, uri: String).returns(Rubydex::Location) }
441
+ def from_prism(prism_location, uri:); end
442
+ end
443
+
427
444
  sig do
428
445
  params(
429
446
  uri: String,
data/rust/Cargo.lock CHANGED
@@ -1048,7 +1048,7 @@ dependencies = [
1048
1048
 
1049
1049
  [[package]]
1050
1050
  name = "rubydex"
1051
- version = "0.1.0"
1051
+ version = "0.2.6"
1052
1052
  dependencies = [
1053
1053
  "assert_cmd",
1054
1054
  "bitflags",
@@ -1072,7 +1072,7 @@ dependencies = [
1072
1072
 
1073
1073
  [[package]]
1074
1074
  name = "rubydex-mcp"
1075
- version = "0.1.0"
1075
+ version = "0.2.6"
1076
1076
  dependencies = [
1077
1077
  "assert_cmd",
1078
1078
  "clap",
@@ -1087,7 +1087,7 @@ dependencies = [
1087
1087
 
1088
1088
  [[package]]
1089
1089
  name = "rubydex-sys"
1090
- version = "0.1.0"
1090
+ version = "0.2.6"
1091
1091
  dependencies = [
1092
1092
  "cbindgen",
1093
1093
  "libc",
@@ -1,9 +1,15 @@
1
1
  [package]
2
2
  name = "rubydex"
3
- version = "0.1.0"
3
+ version = "0.2.6"
4
4
  edition = "2024"
5
5
  rust-version = "1.89.0"
6
6
  license = "MIT"
7
+ description = "High-performance Ruby code indexing and static analysis library."
8
+ homepage = "https://github.com/Shopify/rubydex"
9
+ repository = "https://github.com/Shopify/rubydex"
10
+ readme = "README.md"
11
+ keywords = ["ruby", "indexing", "static-analysis"]
12
+ categories = ["development-tools"]
7
13
 
8
14
  [[bin]]
9
15
  name = "rubydex_cli"