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.
- checksums.yaml +4 -4
- data/README.md +17 -16
- data/THIRD_PARTY_LICENSES.html +6 -6
- data/exe/rubydex_mcp +17 -0
- data/ext/rubydex/definition.c +89 -2
- data/ext/rubydex/document.c +36 -0
- data/ext/rubydex/extconf.rb +8 -0
- data/ext/rubydex/graph.c +32 -18
- data/ext/rubydex/handle.h +21 -5
- data/lib/rubydex/3.2/rubydex.so +0 -0
- data/lib/rubydex/3.3/rubydex.so +0 -0
- data/lib/rubydex/3.4/rubydex.so +0 -0
- data/lib/rubydex/4.0/rubydex.so +0 -0
- data/lib/rubydex/bin/rubydex_mcp +0 -0
- data/lib/rubydex/declaration.rb +3 -3
- data/lib/rubydex/errors.rb +8 -0
- data/lib/rubydex/graph.rb +3 -1
- data/lib/rubydex/librubydex_sys.so +0 -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 +37 -14
- 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/local_graph.rs +38 -0
- data/rust/rubydex/src/indexing/rbs_indexer.rs +19 -1
- data/rust/rubydex/src/indexing/ruby_indexer.rs +10 -0
- data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +5 -1
- data/rust/rubydex/src/indexing.rs +38 -12
- data/rust/rubydex/src/lib.rs +2 -1
- data/rust/rubydex/src/listing.rs +14 -3
- data/rust/rubydex/src/main.rs +35 -7
- 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 +20 -19
- 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/ids.rs +27 -1
- 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 +520 -0
- data/rust/rubydex/src/operation/mod.rs +285 -0
- data/rust/rubydex/src/operation/printer.rs +260 -0
- data/rust/rubydex/src/operation/ruby_builder.rs +2919 -0
- data/rust/rubydex/src/query.rs +114 -33
- data/rust/rubydex/src/resolution.rs +22 -9
- data/rust/rubydex/src/resolution_tests.rs +349 -209
- data/rust/rubydex/src/test_utils/graph_test.rs +19 -4
- data/rust/rubydex/src/test_utils/local_graph_test.rs +7 -6
- data/rust/rubydex/tests/cli.rs +17 -61
- data/rust/rubydex-mcp/Cargo.toml +9 -3
- data/rust/rubydex-mcp/src/server.rs +5 -1
- data/rust/rubydex-sys/Cargo.toml +9 -2
- data/rust/rubydex-sys/src/definition_api.rs +96 -2
- data/rust/rubydex-sys/src/document_api.rs +28 -0
- data/rust/rubydex-sys/src/graph_api.rs +2 -4
- metadata +11 -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: f428a340913b09bd93ef62c2c150af6fee8513747d932c58605b0c262e533ad4
|
|
4
|
+
data.tar.gz: 78917993925bf6c11911a869f8ff6cc0ec27097b03244797a1e54422910ab471
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4b47ac60c6a4920bd85b99154545acf82cd57a2036dd748e181159a286474643def1151f13fbdae99d15244ab89576c769d0a713e42a6f1e667da5a26052cc66
|
|
7
|
+
data.tar.gz: e3a5203e261885c70a7240e0ee8a87ce8412525015c330a980c4d715e9cb6d333405cab81c4c83d0ef01112bd68d858c71e9f948fd29404b30972ae661bc8b0a
|
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/exe/rubydex_mcp
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "rbconfig"
|
|
5
|
+
|
|
6
|
+
host_os = RbConfig::CONFIG.fetch("host_os")
|
|
7
|
+
executable = host_os.match?(/mswin|mingw|cygwin/) ? "rubydex_mcp.exe" : "rubydex_mcp"
|
|
8
|
+
binary = File.expand_path("../lib/rubydex/bin/#{executable}", __dir__)
|
|
9
|
+
|
|
10
|
+
unless File.executable?(binary)
|
|
11
|
+
abort(<<~MESSAGE.chomp)
|
|
12
|
+
rubydex_mcp is not available at #{binary}.
|
|
13
|
+
Install a precompiled rubydex gem, or reinstall rubydex with Cargo available so the MCP executable can be built locally.
|
|
14
|
+
MESSAGE
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
exec(binary, *ARGV)
|
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);
|
|
@@ -195,6 +195,60 @@ static VALUE rdxr_definition_declaration(VALUE self) {
|
|
|
195
195
|
return rb_class_new_instance(2, argv, decl_class);
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
static VALUE rdxi_build_definition(VALUE graph_obj, void *graph, uint64_t definition_id) {
|
|
199
|
+
DefinitionKind kind = rdx_definition_kind(graph, definition_id);
|
|
200
|
+
VALUE defn_class = rdxi_definition_class_for_kind(kind);
|
|
201
|
+
VALUE argv[] = {graph_obj, ULL2NUM(definition_id)};
|
|
202
|
+
|
|
203
|
+
return rb_class_new_instance(2, argv, defn_class);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Definition#lexical_owner -> Rubydex::Definition?
|
|
207
|
+
// Returns the lexically enclosing definition, if any.
|
|
208
|
+
static VALUE rdxr_definition_lexical_owner(VALUE self) {
|
|
209
|
+
HandleData *data;
|
|
210
|
+
TypedData_Get_Struct(self, HandleData, &handle_type, data);
|
|
211
|
+
|
|
212
|
+
void *graph;
|
|
213
|
+
TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
|
|
214
|
+
|
|
215
|
+
const uint64_t *owner_id = rdx_definition_lexical_nesting_id(graph, data->id);
|
|
216
|
+
if (owner_id == NULL) {
|
|
217
|
+
return Qnil;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
VALUE owner = rdxi_build_definition(data->graph_obj, graph, *owner_id);
|
|
221
|
+
free_u64(owner_id);
|
|
222
|
+
|
|
223
|
+
return owner;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Definition#lexical_nesting -> Array<Rubydex::Definition>
|
|
227
|
+
// Returns the lexical nesting from the direct owner up to the root.
|
|
228
|
+
static VALUE rdxr_definition_lexical_nesting(VALUE self) {
|
|
229
|
+
HandleData *data;
|
|
230
|
+
TypedData_Get_Struct(self, HandleData, &handle_type, data);
|
|
231
|
+
|
|
232
|
+
void *graph;
|
|
233
|
+
TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
|
|
234
|
+
|
|
235
|
+
VALUE nesting = rb_ary_new();
|
|
236
|
+
uint64_t definition_id = data->id;
|
|
237
|
+
|
|
238
|
+
while (true) {
|
|
239
|
+
const uint64_t *owner_id = rdx_definition_lexical_nesting_id(graph, definition_id);
|
|
240
|
+
if (owner_id == NULL) {
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
rb_ary_push(nesting, rdxi_build_definition(data->graph_obj, graph, *owner_id));
|
|
245
|
+
definition_id = *owner_id;
|
|
246
|
+
free_u64(owner_id);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
return nesting;
|
|
250
|
+
}
|
|
251
|
+
|
|
198
252
|
static VALUE rdxi_build_constant_reference(VALUE graph_obj, const CConstantReference *cref) {
|
|
199
253
|
VALUE ref_class = (cref->declaration_id == 0)
|
|
200
254
|
? cUnresolvedConstantReference
|
|
@@ -287,6 +341,36 @@ static VALUE rdxr_method_alias_definition_signatures(VALUE self) {
|
|
|
287
341
|
return rdxi_signatures_to_ruby(arr);
|
|
288
342
|
}
|
|
289
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
|
+
|
|
290
374
|
void rdxi_initialize_definition(VALUE mod) {
|
|
291
375
|
mRubydex = mod;
|
|
292
376
|
|
|
@@ -306,6 +390,8 @@ void rdxi_initialize_definition(VALUE mod) {
|
|
|
306
390
|
rb_define_method(cDefinition, "deprecated?", rdxr_definition_deprecated, 0);
|
|
307
391
|
rb_define_method(cDefinition, "name_location", rdxr_definition_name_location, 0);
|
|
308
392
|
rb_define_method(cDefinition, "declaration", rdxr_definition_declaration, 0);
|
|
393
|
+
rb_define_method(cDefinition, "lexical_owner", rdxr_definition_lexical_owner, 0);
|
|
394
|
+
rb_define_method(cDefinition, "lexical_nesting", rdxr_definition_lexical_nesting, 0);
|
|
309
395
|
|
|
310
396
|
cClassDefinition = rb_define_class_under(mRubydex, "ClassDefinition", cDefinition);
|
|
311
397
|
rb_define_method(cClassDefinition, "superclass", rdxr_class_definition_superclass, 0);
|
|
@@ -331,5 +417,6 @@ void rdxi_initialize_definition(VALUE mod) {
|
|
|
331
417
|
cClassVariableDefinition = rb_define_class_under(mRubydex, "ClassVariableDefinition", cDefinition);
|
|
332
418
|
cMethodAliasDefinition = rb_define_class_under(mRubydex, "MethodAliasDefinition", cDefinition);
|
|
333
419
|
rb_define_method(cMethodAliasDefinition, "signatures", rdxr_method_alias_definition_signatures, 0);
|
|
420
|
+
rb_define_method(cMethodAliasDefinition, "target", rdxr_method_alias_definition_target, 0);
|
|
334
421
|
cGlobalVariableAliasDefinition = rb_define_class_under(mRubydex, "GlobalVariableAliasDefinition", cDefinition);
|
|
335
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/extconf.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "mkmf"
|
|
4
|
+
require "fileutils"
|
|
4
5
|
require "pathname"
|
|
5
6
|
|
|
6
7
|
unless system("cargo", "--version", out: File::NULL, err: File::NULL)
|
|
@@ -81,6 +82,12 @@ else
|
|
|
81
82
|
end
|
|
82
83
|
|
|
83
84
|
lib_dir = gem_dir.join("lib").join("rubydex")
|
|
85
|
+
mcp_bin_dir = lib_dir.join("bin")
|
|
86
|
+
FileUtils.mkdir_p(mcp_bin_dir)
|
|
87
|
+
|
|
88
|
+
mcp_executable = Gem.win_platform? ? "rubydex_mcp.exe" : "rubydex_mcp"
|
|
89
|
+
mcp_src = target_dir.join(mcp_executable)
|
|
90
|
+
mcp_dst = mcp_bin_dir.join(mcp_executable)
|
|
84
91
|
|
|
85
92
|
copy_dylib_commands = if Gem.win_platform?
|
|
86
93
|
""
|
|
@@ -107,6 +114,7 @@ new_makefile = makefile.gsub("$(OBJS): $(HDRS) $(ruby_headers)", <<~MAKEFILE.cho
|
|
|
107
114
|
.rust_built: $(RUST_SRCS)
|
|
108
115
|
\t#{cargo_command} || (echo "Compiling Rust failed" && exit 1)
|
|
109
116
|
\t$(COPY) #{bindings_path} #{__dir__}
|
|
117
|
+
\t$(COPY) #{mcp_src} #{mcp_dst}
|
|
110
118
|
\ttouch $@
|
|
111
119
|
|
|
112
120
|
compile_rust: .rust_built
|
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
|
}
|
data/lib/rubydex/3.2/rubydex.so
CHANGED
|
Binary file
|
data/lib/rubydex/3.3/rubydex.so
CHANGED
|
Binary file
|
data/lib/rubydex/3.4/rubydex.so
CHANGED
|
Binary file
|
data/lib/rubydex/4.0/rubydex.so
CHANGED
|
Binary file
|
|
Binary file
|
data/lib/rubydex/declaration.rb
CHANGED
|
@@ -21,9 +21,9 @@ module Rubydex
|
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
class Namespace < Declaration
|
|
24
|
-
#: (String
|
|
25
|
-
def has_ancestor?(
|
|
26
|
-
ancestors.any? { |ancestor| ancestor.name
|
|
24
|
+
#: (*String ancestor_names) -> bool
|
|
25
|
+
def has_ancestor?(*ancestor_names)
|
|
26
|
+
ancestors.any? { |ancestor| ancestor_names.include?(ancestor.name) }
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
data/lib/rubydex/graph.rb
CHANGED
|
@@ -17,6 +17,8 @@ module Rubydex
|
|
|
17
17
|
"tmp",
|
|
18
18
|
].freeze
|
|
19
19
|
|
|
20
|
+
INDEXABLE_EXTENSIONS = [".rb", ".rake", ".rbs", ".ru"].freeze
|
|
21
|
+
|
|
20
22
|
#: String
|
|
21
23
|
attr_accessor :workspace_path
|
|
22
24
|
|
|
@@ -45,7 +47,7 @@ module Rubydex
|
|
|
45
47
|
|
|
46
48
|
if File.directory?(full_path)
|
|
47
49
|
paths << full_path unless IGNORED_DIRECTORIES.include?(entry)
|
|
48
|
-
elsif File.extname(entry)
|
|
50
|
+
elsif INDEXABLE_EXTENSIONS.include?(File.extname(entry))
|
|
49
51
|
paths << full_path
|
|
50
52
|
end
|
|
51
53
|
end
|
|
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