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.
- checksums.yaml +4 -4
- data/README.md +17 -16
- data/THIRD_PARTY_LICENSES.html +6 -6
- data/ext/rubydex/definition.c +33 -2
- data/ext/rubydex/document.c +36 -0
- data/ext/rubydex/graph.c +32 -18
- data/ext/rubydex/handle.h +21 -5
- data/lib/rubydex/bin/rubydex_mcp.exe +0 -0
- data/lib/rubydex/errors.rb +8 -0
- data/lib/rubydex/location.rb +24 -0
- data/lib/rubydex/version.rb +1 -1
- data/lib/rubydex.rb +1 -0
- data/rbi/rubydex.rbi +29 -12
- data/rust/Cargo.lock +3 -3
- data/rust/rubydex/Cargo.toml +7 -1
- data/rust/rubydex/src/dot.rs +609 -0
- data/rust/rubydex/src/indexing/rbs_indexer.rs +19 -1
- data/rust/rubydex/src/indexing/ruby_indexer.rs +4 -0
- data/rust/rubydex/src/lib.rs +1 -1
- data/rust/rubydex/src/main.rs +8 -5
- data/rust/rubydex/src/model/built_in.rs +5 -2
- data/rust/rubydex/src/model/comment.rs +2 -0
- data/rust/rubydex/src/model/declaration.rs +1 -0
- data/rust/rubydex/src/model/definitions.rs +13 -1
- data/rust/rubydex/src/model/document.rs +2 -0
- data/rust/rubydex/src/model/encoding.rs +2 -0
- data/rust/rubydex/src/model/graph.rs +51 -13
- data/rust/rubydex/src/model/identity_maps.rs +3 -0
- data/rust/rubydex/src/model/keywords.rs +3 -0
- data/rust/rubydex/src/model/name.rs +2 -0
- data/rust/rubydex/src/model/string_ref.rs +2 -0
- data/rust/rubydex/src/model/visibility.rs +3 -0
- data/rust/rubydex/src/operation/applier.rs +1 -0
- data/rust/rubydex/src/operation/mod.rs +1 -0
- data/rust/rubydex/src/operation/ruby_builder.rs +4 -0
- data/rust/rubydex/src/query.rs +114 -33
- data/rust/rubydex/src/resolution.rs +16 -8
- data/rust/rubydex/src/resolution_tests.rs +132 -0
- data/rust/rubydex/tests/cli.rs +17 -61
- data/rust/rubydex-mcp/Cargo.toml +9 -3
- data/rust/rubydex-sys/Cargo.toml +9 -2
- data/rust/rubydex-sys/src/definition_api.rs +72 -2
- data/rust/rubydex-sys/src/document_api.rs +28 -0
- data/rust/rubydex-sys/src/graph_api.rs +1 -3
- metadata +4 -4
- data/rust/rubydex/src/visualization/dot.rs +0 -192
- data/rust/rubydex/src/visualization.rs +0 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c776445f3a3589b62c6f4e1987d424f91aa020585434182c4d16087097e28fb1
|
|
4
|
+
data.tar.gz: 4d5e1862670c7dd767bce180f70dda589237bf9696b82c99d971b58f2b6ec9bb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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.
|
|
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
|
-
|
|
94
|
+
bundle install
|
|
90
95
|
```
|
|
91
96
|
|
|
92
|
-
|
|
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
|
|
101
|
+
claude mcp add --scope project rubydex -- bundle exec rubydex_mcp
|
|
95
102
|
```
|
|
96
103
|
|
|
97
|
-
|
|
98
|
-
```
|
|
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
|
-
|
|
109
|
-
the project at startup and provides semantic code intelligence tools
|
|
110
|
-
|
|
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
|
|
data/THIRD_PARTY_LICENSES.html
CHANGED
|
@@ -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://
|
|
3827
|
-
0.
|
|
3826
|
+
href=" https://github.com/Shopify/rubydex ">rubydex
|
|
3827
|
+
0.2.6</a></li>
|
|
3828
3828
|
<li><a
|
|
3829
|
-
href=" https://
|
|
3830
|
-
0.
|
|
3829
|
+
href=" https://github.com/Shopify/rubydex ">rubydex-mcp
|
|
3830
|
+
0.2.6</a></li>
|
|
3831
3831
|
<li><a
|
|
3832
|
-
href=" https://
|
|
3833
|
-
0.
|
|
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>
|
data/ext/rubydex/definition.c
CHANGED
|
@@ -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,
|
|
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
|
}
|
data/ext/rubydex/document.c
CHANGED
|
@@ -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
|
|
20
|
-
//
|
|
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
|
-
|
|
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,
|
|
30
|
+
rb_get_kwargs(opts, &id_self_receiver, 1, 0, &kwarg_val);
|
|
28
31
|
|
|
29
|
-
if (
|
|
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 = {
|
|
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:
|
|
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
|
|
595
|
-
//
|
|
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:
|
|
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
|
|
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:
|
|
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
|
|
639
|
-
//
|
|
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:
|
|
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",
|
|
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
|
-
|
|
30
|
-
data
|
|
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
|
-
|
|
39
|
-
data
|
|
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
|
data/lib/rubydex/location.rb
CHANGED
|
@@ -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
|
data/lib/rubydex/version.rb
CHANGED
data/lib/rubydex.rb
CHANGED
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
|
|
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
|
|
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:
|
|
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
|
|
363
|
-
# singleton methods (e.g., `private_class_method`). Pass `nil`
|
|
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:
|
|
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
|
|
376
|
-
# and `protected` methods. Pass `nil`
|
|
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:
|
|
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:
|
|
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.
|
|
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.
|
|
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.
|
|
1090
|
+
version = "0.2.6"
|
|
1091
1091
|
dependencies = [
|
|
1092
1092
|
"cbindgen",
|
|
1093
1093
|
"libc",
|
data/rust/rubydex/Cargo.toml
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "rubydex"
|
|
3
|
-
version = "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"
|