rubydex 0.1.0.beta11 → 0.1.0.beta12
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/THIRD_PARTY_LICENSES.html +2 -2
- data/ext/rubydex/declaration.c +84 -19
- data/ext/rubydex/definition.c +87 -0
- data/ext/rubydex/document.c +4 -5
- data/ext/rubydex/extconf.rb +12 -1
- data/ext/rubydex/graph.c +177 -8
- data/ext/rubydex/reference.c +29 -10
- data/ext/rubydex/reference.h +2 -3
- data/ext/rubydex/utils.c +30 -8
- data/ext/rubydex/utils.h +10 -4
- data/lib/rubydex/graph.rb +6 -0
- data/lib/rubydex/keyword.rb +17 -0
- data/lib/rubydex/keyword_parameter.rb +13 -0
- data/lib/rubydex/librubydex_sys.so +0 -0
- data/lib/rubydex/mixin.rb +22 -0
- data/lib/rubydex/version.rb +1 -1
- data/lib/rubydex.rb +3 -0
- data/rbi/rubydex.rbi +124 -12
- data/rust/Cargo.lock +4 -4
- data/rust/rubydex/Cargo.toml +1 -1
- data/rust/rubydex/src/diagnostic.rs +1 -0
- data/rust/rubydex/src/indexing/local_graph.rs +9 -9
- data/rust/rubydex/src/indexing/rbs_indexer.rs +17 -20
- data/rust/rubydex/src/indexing/ruby_indexer.rs +155 -4579
- data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +4962 -0
- data/rust/rubydex/src/indexing.rs +5 -5
- data/rust/rubydex/src/integrity.rs +2 -1
- data/rust/rubydex/src/listing.rs +107 -8
- data/rust/rubydex/src/main.rs +2 -2
- data/rust/rubydex/src/model/built_in.rs +83 -0
- data/rust/rubydex/src/model/declaration.rs +116 -33
- data/rust/rubydex/src/model/definitions.rs +91 -11
- data/rust/rubydex/src/model/document.rs +9 -39
- data/rust/rubydex/src/model/graph.rs +353 -155
- data/rust/rubydex/src/model/ids.rs +29 -7
- data/rust/rubydex/src/model/references.rs +5 -5
- data/rust/rubydex/src/model.rs +1 -0
- data/rust/rubydex/src/query.rs +168 -27
- data/rust/rubydex/src/resolution.rs +828 -206
- data/rust/rubydex/src/stats/orphan_report.rs +1 -0
- data/rust/rubydex/src/test_utils/graph_test.rs +56 -5
- data/rust/rubydex/src/visualization/dot.rs +38 -22
- data/rust/rubydex/tests/cli.rs +24 -6
- data/rust/rubydex-mcp/src/server.rs +8 -8
- data/rust/rubydex-mcp/tests/mcp.rs +1 -1
- data/rust/rubydex-sys/src/declaration_api.rs +66 -50
- data/rust/rubydex-sys/src/definition_api.rs +150 -59
- data/rust/rubydex-sys/src/document_api.rs +31 -0
- data/rust/rubydex-sys/src/graph_api.rs +386 -138
- data/rust/rubydex-sys/src/lib.rs +70 -0
- data/rust/rubydex-sys/src/reference_api.rs +136 -64
- metadata +7 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 98e6dcc146395bd17fb654d336ad198a58c4726a2345d86c710a644ab85e415d
|
|
4
|
+
data.tar.gz: c27b9aeda854bac93d5be6c7cde3b77da6c3a2c564baf66c5d5dab4b8075e9e5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4f807b20f75639d56c7df1ba831979d8f5880ac8bfcbabe4f0e23ac2709157f3f49d9feb1e4862645b03b348cdba982e515e9a8da262cab1d4e29e179d937acc
|
|
7
|
+
data.tar.gz: f4938ecf9d5e6e9fb9cdaa4bdb52318c8988814b7561462a129be1ec5923817a0af1753b09b54fbb5e3f23dbf3f6b9a38e56d788fff420a89197fe5fd31b077d
|
data/THIRD_PARTY_LICENSES.html
CHANGED
|
@@ -3336,10 +3336,10 @@ limitations under the License.
|
|
|
3336
3336
|
<ul class="license-used-by">
|
|
3337
3337
|
<li><a
|
|
3338
3338
|
href=" https://github.com/ruby/rbs.git ">ruby-rbs-sys
|
|
3339
|
-
0.
|
|
3339
|
+
0.3.0</a></li>
|
|
3340
3340
|
<li><a
|
|
3341
3341
|
href=" https://github.com/ruby/rbs.git ">ruby-rbs
|
|
3342
|
-
0.
|
|
3342
|
+
0.3.0</a></li>
|
|
3343
3343
|
</ul>
|
|
3344
3344
|
<pre class="license-text">Copyright (c) <year> <owner>
|
|
3345
3345
|
|
data/ext/rubydex/declaration.c
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
#include "definition.h"
|
|
3
3
|
#include "graph.h"
|
|
4
4
|
#include "handle.h"
|
|
5
|
-
#include "reference.h"
|
|
6
5
|
#include "rustbindings.h"
|
|
7
6
|
#include "utils.h"
|
|
8
7
|
|
|
@@ -93,11 +92,10 @@ static VALUE declaration_definitions_yield(VALUE args) {
|
|
|
93
92
|
HandleData *data;
|
|
94
93
|
TypedData_Get_Struct(self, HandleData, &handle_type, data);
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
VALUE
|
|
100
|
-
VALUE defn_class = rdxi_definition_class_for_kind(kind);
|
|
95
|
+
CDefinition defn;
|
|
96
|
+
while (rdx_definitions_iter_next(iter, &defn)) {
|
|
97
|
+
VALUE argv[] = {data->graph_obj, ULL2NUM(defn.id)};
|
|
98
|
+
VALUE defn_class = rdxi_definition_class_for_kind(defn.kind);
|
|
101
99
|
VALUE handle = rb_class_new_instance(2, argv, defn_class);
|
|
102
100
|
rb_yield(handle);
|
|
103
101
|
}
|
|
@@ -318,27 +316,30 @@ static VALUE rdxr_declaration_members(VALUE self) {
|
|
|
318
316
|
return self;
|
|
319
317
|
}
|
|
320
318
|
|
|
321
|
-
// Size function for
|
|
322
|
-
static VALUE
|
|
319
|
+
// Size function for constant declaration references enumerator
|
|
320
|
+
static VALUE constant_declaration_references_size(VALUE self, VALUE _args, VALUE _eobj) {
|
|
323
321
|
HandleData *data;
|
|
324
322
|
TypedData_Get_Struct(self, HandleData, &handle_type, data);
|
|
325
323
|
|
|
326
324
|
void *graph;
|
|
327
325
|
TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
|
|
328
326
|
|
|
329
|
-
struct
|
|
330
|
-
|
|
331
|
-
|
|
327
|
+
struct ConstantReferencesIter *iter = rdx_declaration_constant_references_iter_new(graph, data->id);
|
|
328
|
+
if (iter == NULL) {
|
|
329
|
+
rb_raise(rb_eRuntimeError, "Declaration not found");
|
|
330
|
+
}
|
|
332
331
|
|
|
332
|
+
size_t len = rdx_constant_references_iter_len(iter);
|
|
333
|
+
rdx_constant_references_iter_free(iter);
|
|
333
334
|
return SIZET2NUM(len);
|
|
334
335
|
}
|
|
335
336
|
|
|
336
|
-
//
|
|
337
|
-
//
|
|
338
|
-
|
|
339
|
-
static VALUE rdxr_declaration_references(VALUE self) {
|
|
337
|
+
// Namespace#references, Constant#references, ConstantAlias#references
|
|
338
|
+
// Returns an enumerator that yields constant references to this declaration
|
|
339
|
+
static VALUE rdxr_constant_declaration_references(VALUE self) {
|
|
340
340
|
if (!rb_block_given_p()) {
|
|
341
|
-
return rb_enumeratorize_with_size(self, rb_str_new2("references"), 0, NULL,
|
|
341
|
+
return rb_enumeratorize_with_size(self, rb_str_new2("references"), 0, NULL,
|
|
342
|
+
constant_declaration_references_size);
|
|
342
343
|
}
|
|
343
344
|
|
|
344
345
|
HandleData *data;
|
|
@@ -347,13 +348,65 @@ static VALUE rdxr_declaration_references(VALUE self) {
|
|
|
347
348
|
void *graph;
|
|
348
349
|
TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
|
|
349
350
|
|
|
350
|
-
void *iter =
|
|
351
|
+
void *iter = rdx_declaration_constant_references_iter_new(graph, data->id);
|
|
352
|
+
if (iter == NULL) {
|
|
353
|
+
rb_raise(rb_eRuntimeError, "Declaration not found");
|
|
354
|
+
}
|
|
355
|
+
|
|
351
356
|
VALUE args = rb_ary_new_from_args(2, data->graph_obj, ULL2NUM((uintptr_t)iter));
|
|
352
|
-
rb_ensure(
|
|
357
|
+
rb_ensure(rdxi_constant_references_yield, args, rdxi_constant_references_ensure, args);
|
|
353
358
|
|
|
354
359
|
return self;
|
|
355
360
|
}
|
|
356
361
|
|
|
362
|
+
// Size function for method declaration references enumerator
|
|
363
|
+
static VALUE method_declaration_references_size(VALUE self, VALUE _args, VALUE _eobj) {
|
|
364
|
+
HandleData *data;
|
|
365
|
+
TypedData_Get_Struct(self, HandleData, &handle_type, data);
|
|
366
|
+
|
|
367
|
+
void *graph;
|
|
368
|
+
TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
|
|
369
|
+
|
|
370
|
+
struct MethodReferencesIter *iter = rdx_declaration_method_references_iter_new(graph, data->id);
|
|
371
|
+
if (iter == NULL) {
|
|
372
|
+
rb_raise(rb_eRuntimeError, "Declaration not found");
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
size_t len = rdx_method_references_iter_len(iter);
|
|
376
|
+
rdx_method_references_iter_free(iter);
|
|
377
|
+
return SIZET2NUM(len);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Method#references
|
|
381
|
+
// Returns an enumerator that yields method references to this declaration
|
|
382
|
+
static VALUE rdxr_method_declaration_references(VALUE self) {
|
|
383
|
+
if (!rb_block_given_p()) {
|
|
384
|
+
return rb_enumeratorize_with_size(self, rb_str_new2("references"), 0, NULL,
|
|
385
|
+
method_declaration_references_size);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
HandleData *data;
|
|
389
|
+
TypedData_Get_Struct(self, HandleData, &handle_type, data);
|
|
390
|
+
|
|
391
|
+
void *graph;
|
|
392
|
+
TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
|
|
393
|
+
|
|
394
|
+
void *iter = rdx_declaration_method_references_iter_new(graph, data->id);
|
|
395
|
+
if (iter == NULL) {
|
|
396
|
+
rb_raise(rb_eRuntimeError, "Declaration not found");
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
VALUE args = rb_ary_new_from_args(2, data->graph_obj, ULL2NUM((uintptr_t)iter));
|
|
400
|
+
rb_ensure(rdxi_method_references_yield, args, rdxi_method_references_ensure, args);
|
|
401
|
+
|
|
402
|
+
return self;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Placeholder for variable declarations that don't yet support references
|
|
406
|
+
static VALUE rdxr_variable_declaration_references(VALUE self) {
|
|
407
|
+
return rb_ary_new();
|
|
408
|
+
}
|
|
409
|
+
|
|
357
410
|
void rdxi_initialize_declaration(VALUE mRubydex) {
|
|
358
411
|
cDeclaration = rb_define_class_under(mRubydex, "Declaration", rb_cObject);
|
|
359
412
|
cNamespace = rb_define_class_under(mRubydex, "Namespace", cDeclaration);
|
|
@@ -373,10 +426,10 @@ void rdxi_initialize_declaration(VALUE mRubydex) {
|
|
|
373
426
|
rb_define_method(cDeclaration, "name", rdxr_declaration_name, 0);
|
|
374
427
|
rb_define_method(cDeclaration, "unqualified_name", rdxr_declaration_unqualified_name, 0);
|
|
375
428
|
rb_define_method(cDeclaration, "definitions", rdxr_declaration_definitions, 0);
|
|
376
|
-
rb_define_method(cDeclaration, "references", rdxr_declaration_references, 0);
|
|
377
429
|
rb_define_method(cDeclaration, "owner", rdxr_declaration_owner, 0);
|
|
378
430
|
|
|
379
431
|
// Namespace only methods
|
|
432
|
+
rb_define_method(cNamespace, "references", rdxr_constant_declaration_references, 0);
|
|
380
433
|
rb_define_method(cNamespace, "member", rdxr_declaration_member, 1);
|
|
381
434
|
rb_define_method(cNamespace, "find_member", rdxr_declaration_find_member, -1);
|
|
382
435
|
rb_define_method(cNamespace, "singleton_class", rdxr_declaration_singleton_class, 0);
|
|
@@ -384,5 +437,17 @@ void rdxi_initialize_declaration(VALUE mRubydex) {
|
|
|
384
437
|
rb_define_method(cNamespace, "descendants", rdxr_declaration_descendants, 0);
|
|
385
438
|
rb_define_method(cNamespace, "members", rdxr_declaration_members, 0);
|
|
386
439
|
|
|
440
|
+
// Constant and ConstantAlias have constant references
|
|
441
|
+
rb_define_method(cConstant, "references", rdxr_constant_declaration_references, 0);
|
|
442
|
+
rb_define_method(cConstantAlias, "references", rdxr_constant_declaration_references, 0);
|
|
443
|
+
|
|
444
|
+
// Method has method references
|
|
445
|
+
rb_define_method(cMethod, "references", rdxr_method_declaration_references, 0);
|
|
446
|
+
|
|
447
|
+
// Variable declarations don't yet support references
|
|
448
|
+
rb_define_method(cGlobalVariable, "references", rdxr_variable_declaration_references, 0);
|
|
449
|
+
rb_define_method(cInstanceVariable, "references", rdxr_variable_declaration_references, 0);
|
|
450
|
+
rb_define_method(cClassVariable, "references", rdxr_variable_declaration_references, 0);
|
|
451
|
+
|
|
387
452
|
rb_funcall(rb_singleton_class(cDeclaration), rb_intern("private"), 1, ID2SYM(rb_intern("new")));
|
|
388
453
|
}
|
data/ext/rubydex/definition.c
CHANGED
|
@@ -2,10 +2,14 @@
|
|
|
2
2
|
#include "graph.h"
|
|
3
3
|
#include "handle.h"
|
|
4
4
|
#include "location.h"
|
|
5
|
+
#include "reference.h"
|
|
5
6
|
#include "ruby/internal/scan_args.h"
|
|
6
7
|
#include "rustbindings.h"
|
|
7
8
|
|
|
8
9
|
static VALUE mRubydex;
|
|
10
|
+
static VALUE cInclude;
|
|
11
|
+
static VALUE cPrepend;
|
|
12
|
+
static VALUE cExtend;
|
|
9
13
|
VALUE cComment;
|
|
10
14
|
VALUE cDefinition;
|
|
11
15
|
VALUE cClassDefinition;
|
|
@@ -14,6 +18,7 @@ VALUE cModuleDefinition;
|
|
|
14
18
|
VALUE cConstantDefinition;
|
|
15
19
|
VALUE cConstantAliasDefinition;
|
|
16
20
|
VALUE cConstantVisibilityDefinition;
|
|
21
|
+
VALUE cMethodVisibilityDefinition;
|
|
17
22
|
VALUE cMethodDefinition;
|
|
18
23
|
VALUE cAttrAccessorDefinition;
|
|
19
24
|
VALUE cAttrReaderDefinition;
|
|
@@ -39,6 +44,8 @@ VALUE rdxi_definition_class_for_kind(DefinitionKind kind) {
|
|
|
39
44
|
return cConstantAliasDefinition;
|
|
40
45
|
case DefinitionKind_ConstantVisibility:
|
|
41
46
|
return cConstantVisibilityDefinition;
|
|
47
|
+
case DefinitionKind_MethodVisibility:
|
|
48
|
+
return cMethodVisibilityDefinition;
|
|
42
49
|
case DefinitionKind_Method:
|
|
43
50
|
return cMethodDefinition;
|
|
44
51
|
case DefinitionKind_AttrAccessor:
|
|
@@ -164,9 +171,81 @@ static VALUE rdxr_definition_name_location(VALUE self) {
|
|
|
164
171
|
return location;
|
|
165
172
|
}
|
|
166
173
|
|
|
174
|
+
static VALUE rdxi_build_constant_reference(VALUE graph_obj, const CConstantReference *cref) {
|
|
175
|
+
VALUE ref_class = (cref->declaration_id == 0)
|
|
176
|
+
? cUnresolvedConstantReference
|
|
177
|
+
: cResolvedConstantReference;
|
|
178
|
+
|
|
179
|
+
VALUE argv[] = {graph_obj, ULL2NUM(cref->id)};
|
|
180
|
+
return rb_class_new_instance(2, argv, ref_class);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// ClassDefinition#superclass -> ConstantReference?
|
|
184
|
+
static VALUE rdxr_class_definition_superclass(VALUE self) {
|
|
185
|
+
HandleData *data;
|
|
186
|
+
TypedData_Get_Struct(self, HandleData, &handle_type, data);
|
|
187
|
+
|
|
188
|
+
void *graph;
|
|
189
|
+
TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
|
|
190
|
+
|
|
191
|
+
const CConstantReference *ref = rdx_class_definition_superclass(graph, data->id);
|
|
192
|
+
if (ref == NULL) {
|
|
193
|
+
return Qnil;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
VALUE result = rdxi_build_constant_reference(data->graph_obj, ref);
|
|
197
|
+
free_c_constant_reference(ref);
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
static VALUE rdxi_mixin_class_for_kind(MixinKind kind) {
|
|
202
|
+
switch (kind) {
|
|
203
|
+
case MixinKind_Include:
|
|
204
|
+
return cInclude;
|
|
205
|
+
case MixinKind_Prepend:
|
|
206
|
+
return cPrepend;
|
|
207
|
+
case MixinKind_Extend:
|
|
208
|
+
return cExtend;
|
|
209
|
+
default:
|
|
210
|
+
rb_raise(rb_eRuntimeError, "Unknown MixinKind: %d", kind);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Definition#mixins -> [Rubydex::Mixin]
|
|
215
|
+
static VALUE rdxr_definition_mixins(VALUE self) {
|
|
216
|
+
HandleData *data;
|
|
217
|
+
TypedData_Get_Struct(self, HandleData, &handle_type, data);
|
|
218
|
+
|
|
219
|
+
void *graph;
|
|
220
|
+
TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
|
|
221
|
+
|
|
222
|
+
MixinsIter *iter = rdx_definition_mixins(graph, data->id);
|
|
223
|
+
if (iter == NULL) {
|
|
224
|
+
rb_raise(rb_eRuntimeError, "Tried to get mixins for a definition that isn't a namespace");
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
size_t len = rdx_mixins_iter_len(iter);
|
|
228
|
+
VALUE ary = rb_ary_new_capa((long)len);
|
|
229
|
+
|
|
230
|
+
CMixin entry;
|
|
231
|
+
while (rdx_mixins_iter_next(iter, &entry)) {
|
|
232
|
+
VALUE constant_ref = rdxi_build_constant_reference(data->graph_obj, &entry.constant_reference);
|
|
233
|
+
VALUE mixin_class = rdxi_mixin_class_for_kind(entry.kind);
|
|
234
|
+
VALUE mixin = rb_class_new_instance(1, &constant_ref, mixin_class);
|
|
235
|
+
rb_ary_push(ary, mixin);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
rdx_mixins_iter_free(iter);
|
|
239
|
+
return ary;
|
|
240
|
+
}
|
|
241
|
+
|
|
167
242
|
void rdxi_initialize_definition(VALUE mod) {
|
|
168
243
|
mRubydex = mod;
|
|
169
244
|
|
|
245
|
+
cInclude = rb_const_get(mRubydex, rb_intern("Include"));
|
|
246
|
+
cPrepend = rb_const_get(mRubydex, rb_intern("Prepend"));
|
|
247
|
+
cExtend = rb_const_get(mRubydex, rb_intern("Extend"));
|
|
248
|
+
|
|
170
249
|
cComment = rb_define_class_under(mRubydex, "Comment", rb_cObject);
|
|
171
250
|
|
|
172
251
|
cDefinition = rb_define_class_under(mRubydex, "Definition", rb_cObject);
|
|
@@ -180,11 +259,19 @@ void rdxi_initialize_definition(VALUE mod) {
|
|
|
180
259
|
rb_define_method(cDefinition, "name_location", rdxr_definition_name_location, 0);
|
|
181
260
|
|
|
182
261
|
cClassDefinition = rb_define_class_under(mRubydex, "ClassDefinition", cDefinition);
|
|
262
|
+
rb_define_method(cClassDefinition, "superclass", rdxr_class_definition_superclass, 0);
|
|
263
|
+
rb_define_method(cClassDefinition, "mixins", rdxr_definition_mixins, 0);
|
|
264
|
+
|
|
183
265
|
cSingletonClassDefinition = rb_define_class_under(mRubydex, "SingletonClassDefinition", cDefinition);
|
|
266
|
+
rb_define_method(cSingletonClassDefinition, "mixins", rdxr_definition_mixins, 0);
|
|
267
|
+
|
|
184
268
|
cModuleDefinition = rb_define_class_under(mRubydex, "ModuleDefinition", cDefinition);
|
|
269
|
+
rb_define_method(cModuleDefinition, "mixins", rdxr_definition_mixins, 0);
|
|
270
|
+
|
|
185
271
|
cConstantDefinition = rb_define_class_under(mRubydex, "ConstantDefinition", cDefinition);
|
|
186
272
|
cConstantAliasDefinition = rb_define_class_under(mRubydex, "ConstantAliasDefinition", cDefinition);
|
|
187
273
|
cConstantVisibilityDefinition = rb_define_class_under(mRubydex, "ConstantVisibilityDefinition", cDefinition);
|
|
274
|
+
cMethodVisibilityDefinition = rb_define_class_under(mRubydex, "MethodVisibilityDefinition", cDefinition);
|
|
188
275
|
cMethodDefinition = rb_define_class_under(mRubydex, "MethodDefinition", cDefinition);
|
|
189
276
|
cAttrAccessorDefinition = rb_define_class_under(mRubydex, "AttrAccessorDefinition", cDefinition);
|
|
190
277
|
cAttrReaderDefinition = rb_define_class_under(mRubydex, "AttrReaderDefinition", cDefinition);
|
data/ext/rubydex/document.c
CHANGED
|
@@ -33,11 +33,10 @@ static VALUE document_definitions_yield(VALUE args) {
|
|
|
33
33
|
HandleData *data;
|
|
34
34
|
TypedData_Get_Struct(self, HandleData, &handle_type, data);
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
VALUE
|
|
40
|
-
VALUE defn_class = rdxi_definition_class_for_kind(kind);
|
|
36
|
+
CDefinition defn;
|
|
37
|
+
while (rdx_definitions_iter_next(iter, &defn)) {
|
|
38
|
+
VALUE argv[] = {data->graph_obj, ULL2NUM(defn.id)};
|
|
39
|
+
VALUE defn_class = rdxi_definition_class_for_kind(defn.kind);
|
|
41
40
|
VALUE handle = rb_class_new_instance(2, argv, defn_class);
|
|
42
41
|
rb_yield(handle);
|
|
43
42
|
}
|
data/ext/rubydex/extconf.rb
CHANGED
|
@@ -8,7 +8,18 @@ unless system("cargo", "--version", out: File::NULL, err: File::NULL)
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
gem_dir = Pathname.new("../..").expand_path(__dir__)
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
# Use release mode for the compilation if:
|
|
13
|
+
# - The RELEASE environment variable is set
|
|
14
|
+
# - We're not working on Rubydex (BUNDLE_GEMFILE doesn't point to Rubydex's own Gemfile)
|
|
15
|
+
#
|
|
16
|
+
# We only need debug builds when working on Rubydex itself and on CI. This approach also lets people install Rubydex
|
|
17
|
+
# from the git source and get a release mode build
|
|
18
|
+
|
|
19
|
+
bundle_gemfile = ENV["BUNDLE_GEMFILE"]
|
|
20
|
+
developing_rubydex = bundle_gemfile && Pathname.new(bundle_gemfile).expand_path.dirname == gem_dir
|
|
21
|
+
release = ENV["RELEASE"] || !developing_rubydex
|
|
22
|
+
|
|
12
23
|
root_dir = gem_dir.join("rust")
|
|
13
24
|
target_dir = root_dir.join("target")
|
|
14
25
|
target_dir = target_dir.join("x86_64-pc-windows-gnu") if Gem.win_platform?
|
data/ext/rubydex/graph.c
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
static VALUE cGraph;
|
|
12
12
|
static VALUE mRubydex;
|
|
13
|
+
static VALUE cKeyword;
|
|
14
|
+
static VALUE cKeywordParameter;
|
|
13
15
|
|
|
14
16
|
// Free function for the custom Graph allocator. We always have to call into Rust to free data allocated by it
|
|
15
17
|
static void graph_free(void *ptr) {
|
|
@@ -246,9 +248,9 @@ static VALUE graph_constant_references_size(VALUE self, VALUE _args, VALUE _eobj
|
|
|
246
248
|
void *graph;
|
|
247
249
|
TypedData_Get_Struct(self, void *, &graph_type, graph);
|
|
248
250
|
|
|
249
|
-
|
|
250
|
-
size_t len =
|
|
251
|
-
|
|
251
|
+
struct ConstantReferencesIter *iter = rdx_graph_constant_references_iter_new(graph);
|
|
252
|
+
size_t len = rdx_constant_references_iter_len(iter);
|
|
253
|
+
rdx_constant_references_iter_free(iter);
|
|
252
254
|
|
|
253
255
|
return SIZET2NUM(len);
|
|
254
256
|
}
|
|
@@ -266,7 +268,7 @@ static VALUE rdxr_graph_constant_references(VALUE self) {
|
|
|
266
268
|
|
|
267
269
|
void *iter = rdx_graph_constant_references_iter_new(graph);
|
|
268
270
|
VALUE args = rb_ary_new_from_args(2, self, ULL2NUM((uintptr_t)iter));
|
|
269
|
-
rb_ensure(
|
|
271
|
+
rb_ensure(rdxi_constant_references_yield, args, rdxi_constant_references_ensure, args);
|
|
270
272
|
|
|
271
273
|
return self;
|
|
272
274
|
}
|
|
@@ -276,9 +278,9 @@ static VALUE graph_method_references_size(VALUE self, VALUE _args, VALUE _eobj)
|
|
|
276
278
|
void *graph;
|
|
277
279
|
TypedData_Get_Struct(self, void *, &graph_type, graph);
|
|
278
280
|
|
|
279
|
-
|
|
280
|
-
size_t len =
|
|
281
|
-
|
|
281
|
+
struct MethodReferencesIter *iter = rdx_graph_method_references_iter_new(graph);
|
|
282
|
+
size_t len = rdx_method_references_iter_len(iter);
|
|
283
|
+
rdx_method_references_iter_free(iter);
|
|
282
284
|
|
|
283
285
|
return SIZET2NUM(len);
|
|
284
286
|
}
|
|
@@ -296,7 +298,7 @@ static VALUE rdxr_graph_method_references(VALUE self) {
|
|
|
296
298
|
|
|
297
299
|
void *iter = rdx_graph_method_references_iter_new(graph);
|
|
298
300
|
VALUE args = rb_ary_new_from_args(2, self, ULL2NUM((uintptr_t)iter));
|
|
299
|
-
rb_ensure(
|
|
301
|
+
rb_ensure(rdxi_method_references_yield, args, rdxi_method_references_ensure, args);
|
|
300
302
|
|
|
301
303
|
return self;
|
|
302
304
|
}
|
|
@@ -488,9 +490,170 @@ static VALUE rdxr_graph_diagnostics(VALUE self) {
|
|
|
488
490
|
return diagnostics;
|
|
489
491
|
}
|
|
490
492
|
|
|
493
|
+
// Helper: convert a CompletionResult into a Ruby array, raising ArgumentError on error.
|
|
494
|
+
static VALUE completion_result_to_ruby_array(struct CompletionResult result, VALUE graph_obj) {
|
|
495
|
+
if (result.error != NULL) {
|
|
496
|
+
VALUE msg = rb_utf8_str_new_cstr(result.error);
|
|
497
|
+
free_c_string(result.error);
|
|
498
|
+
rb_raise(rb_eArgError, "%s", StringValueCStr(msg));
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
CompletionCandidateArray *array = result.candidates;
|
|
502
|
+
if (array == NULL) {
|
|
503
|
+
return rb_ary_new();
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if (array->len == 0) {
|
|
507
|
+
rdx_completion_candidates_free(array);
|
|
508
|
+
return rb_ary_new();
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
VALUE ruby_array = rb_ary_new_capa((long)array->len);
|
|
512
|
+
|
|
513
|
+
for (size_t i = 0; i < array->len; i++) {
|
|
514
|
+
CCompletionCandidate item = array->items[i];
|
|
515
|
+
VALUE obj;
|
|
516
|
+
|
|
517
|
+
switch (item.kind) {
|
|
518
|
+
case CCompletionCandidateKind_Declaration: {
|
|
519
|
+
VALUE decl_class = rdxi_declaration_class_for_kind(item.declaration->kind);
|
|
520
|
+
VALUE argv[] = {graph_obj, ULL2NUM(item.declaration->id)};
|
|
521
|
+
obj = rb_class_new_instance(2, argv, decl_class);
|
|
522
|
+
break;
|
|
523
|
+
}
|
|
524
|
+
case CCompletionCandidateKind_Keyword: {
|
|
525
|
+
VALUE argv[2] = {
|
|
526
|
+
rb_utf8_str_new_cstr(item.name),
|
|
527
|
+
rb_utf8_str_new_cstr(item.documentation),
|
|
528
|
+
};
|
|
529
|
+
obj = rb_class_new_instance(2, argv, cKeyword);
|
|
530
|
+
break;
|
|
531
|
+
}
|
|
532
|
+
case CCompletionCandidateKind_KeywordParameter: {
|
|
533
|
+
VALUE argv[1] = { rb_utf8_str_new_cstr(item.name) };
|
|
534
|
+
obj = rb_class_new_instance(1, argv, cKeywordParameter);
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
537
|
+
default:
|
|
538
|
+
rdx_completion_candidates_free(array);
|
|
539
|
+
rb_raise(rb_eRuntimeError, "Unknown CCompletionCandidateKind: %d", item.kind);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
rb_ary_push(ruby_array, obj);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
rdx_completion_candidates_free(array);
|
|
546
|
+
return ruby_array;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
// Graph#complete_expression: (Array[String] nesting) -> Array[Declaration | Keyword]
|
|
550
|
+
// Returns completion candidates for an expression context.
|
|
551
|
+
// The nesting array represents the lexical scope stack
|
|
552
|
+
static VALUE rdxr_graph_complete_expression(VALUE self, VALUE nesting) {
|
|
553
|
+
rdxi_check_array_of_strings(nesting);
|
|
554
|
+
|
|
555
|
+
void *graph;
|
|
556
|
+
TypedData_Get_Struct(self, void *, &graph_type, graph);
|
|
557
|
+
|
|
558
|
+
size_t nesting_count = RARRAY_LEN(nesting);
|
|
559
|
+
char **converted_nesting = rdxi_str_array_to_char(nesting, nesting_count);
|
|
560
|
+
|
|
561
|
+
struct CompletionResult result =
|
|
562
|
+
rdx_graph_complete_expression(graph, (const char *const *)converted_nesting, nesting_count);
|
|
563
|
+
|
|
564
|
+
rdxi_free_str_array(converted_nesting, nesting_count);
|
|
565
|
+
return completion_result_to_ruby_array(result, self);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// Graph#complete_namespace_access: (String name) -> Array[Declaration]
|
|
569
|
+
// Returns completion candidates after a namespace access operator (e.g., `Foo::`).
|
|
570
|
+
static VALUE rdxr_graph_complete_namespace_access(VALUE self, VALUE name) {
|
|
571
|
+
Check_Type(name, T_STRING);
|
|
572
|
+
|
|
573
|
+
void *graph;
|
|
574
|
+
TypedData_Get_Struct(self, void *, &graph_type, graph);
|
|
575
|
+
|
|
576
|
+
struct CompletionResult result = rdx_graph_complete_namespace_access(graph, StringValueCStr(name));
|
|
577
|
+
return completion_result_to_ruby_array(result, self);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// Graph#complete_method_call: (String name) -> Array[Declaration]
|
|
581
|
+
// Returns completion candidates after a method call operator (e.g., `foo.`).
|
|
582
|
+
static VALUE rdxr_graph_complete_method_call(VALUE self, VALUE name) {
|
|
583
|
+
Check_Type(name, T_STRING);
|
|
584
|
+
|
|
585
|
+
void *graph;
|
|
586
|
+
TypedData_Get_Struct(self, void *, &graph_type, graph);
|
|
587
|
+
|
|
588
|
+
struct CompletionResult result = rdx_graph_complete_method_call(graph, StringValueCStr(name));
|
|
589
|
+
return completion_result_to_ruby_array(result, self);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// Graph#complete_method_argument: (String name, Array[String] nesting) -> Array[Declaration | Keyword | KeywordParameter]
|
|
593
|
+
// Returns completion candidates inside a method call's argument list (e.g., `foo.bar(|)`).
|
|
594
|
+
static VALUE rdxr_graph_complete_method_argument(VALUE self, VALUE name, VALUE nesting) {
|
|
595
|
+
Check_Type(name, T_STRING);
|
|
596
|
+
rdxi_check_array_of_strings(nesting);
|
|
597
|
+
|
|
598
|
+
void *graph;
|
|
599
|
+
TypedData_Get_Struct(self, void *, &graph_type, graph);
|
|
600
|
+
|
|
601
|
+
size_t nesting_count = RARRAY_LEN(nesting);
|
|
602
|
+
char **converted_nesting = rdxi_str_array_to_char(nesting, nesting_count);
|
|
603
|
+
|
|
604
|
+
struct CompletionResult result = rdx_graph_complete_method_argument(
|
|
605
|
+
graph, StringValueCStr(name), (const char *const *)converted_nesting, nesting_count);
|
|
606
|
+
|
|
607
|
+
rdxi_free_str_array(converted_nesting, nesting_count);
|
|
608
|
+
return completion_result_to_ruby_array(result, self);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
// Graph#exclude_paths: (Array[String] paths) -> void
|
|
612
|
+
// Excludes the given paths from file discovery during indexing.
|
|
613
|
+
static VALUE rdxr_graph_exclude_paths(VALUE self, VALUE paths) {
|
|
614
|
+
Check_Type(paths, T_ARRAY);
|
|
615
|
+
rdxi_check_array_of_strings(paths);
|
|
616
|
+
|
|
617
|
+
size_t length = RARRAY_LEN(paths);
|
|
618
|
+
char **converted_paths = rdxi_str_array_to_char(paths, length);
|
|
619
|
+
|
|
620
|
+
void *graph;
|
|
621
|
+
TypedData_Get_Struct(self, void*, &graph_type, graph);
|
|
622
|
+
|
|
623
|
+
rdx_graph_exclude_paths(graph, (const char **)converted_paths, length);
|
|
624
|
+
rdxi_free_str_array(converted_paths, length);
|
|
625
|
+
|
|
626
|
+
return Qnil;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// Graph#excluded_paths: () -> Array[String]
|
|
630
|
+
// Returns the list of paths currently excluded from file discovery.
|
|
631
|
+
static VALUE rdxr_graph_excluded_paths(VALUE self) {
|
|
632
|
+
void *graph;
|
|
633
|
+
TypedData_Get_Struct(self, void*, &graph_type, graph);
|
|
634
|
+
|
|
635
|
+
size_t out_count = 0;
|
|
636
|
+
const char *const *results = rdx_graph_excluded_paths(graph, &out_count);
|
|
637
|
+
|
|
638
|
+
if (results == NULL) {
|
|
639
|
+
return rb_ary_new();
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
VALUE array = rb_ary_new_capa((long)out_count);
|
|
643
|
+
for (size_t i = 0; i < out_count; i++) {
|
|
644
|
+
rb_ary_push(array, rb_utf8_str_new_cstr(results[i]));
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
free_c_string_array(results, out_count);
|
|
648
|
+
return array;
|
|
649
|
+
}
|
|
650
|
+
|
|
491
651
|
void rdxi_initialize_graph(VALUE moduleRubydex) {
|
|
492
652
|
mRubydex = moduleRubydex;
|
|
493
653
|
cGraph = rb_define_class_under(mRubydex, "Graph", rb_cObject);
|
|
654
|
+
cKeyword = rb_define_class_under(mRubydex, "Keyword", rb_cObject);
|
|
655
|
+
cKeywordParameter = rb_define_class_under(mRubydex, "KeywordParameter", rb_cObject);
|
|
656
|
+
|
|
494
657
|
rb_define_alloc_func(cGraph, rdxr_graph_alloc);
|
|
495
658
|
rb_define_method(cGraph, "index_all", rdxr_graph_index_all, 1);
|
|
496
659
|
rb_define_method(cGraph, "index_source", rdxr_graph_index_source, 3);
|
|
@@ -509,4 +672,10 @@ void rdxi_initialize_graph(VALUE moduleRubydex) {
|
|
|
509
672
|
rb_define_method(cGraph, "encoding=", rdxr_graph_set_encoding, 1);
|
|
510
673
|
rb_define_method(cGraph, "resolve_require_path", rdxr_graph_resolve_require_path, 2);
|
|
511
674
|
rb_define_method(cGraph, "require_paths", rdxr_graph_require_paths, 1);
|
|
675
|
+
rb_define_method(cGraph, "complete_expression", rdxr_graph_complete_expression, 1);
|
|
676
|
+
rb_define_method(cGraph, "complete_namespace_access", rdxr_graph_complete_namespace_access, 1);
|
|
677
|
+
rb_define_method(cGraph, "complete_method_call", rdxr_graph_complete_method_call, 1);
|
|
678
|
+
rb_define_method(cGraph, "complete_method_argument", rdxr_graph_complete_method_argument, 2);
|
|
679
|
+
rb_define_method(cGraph, "exclude_paths", rdxr_graph_exclude_paths, 1);
|
|
680
|
+
rb_define_method(cGraph, "excluded_paths", rdxr_graph_excluded_paths, 0);
|
|
512
681
|
}
|
data/ext/rubydex/reference.c
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#include "reference.h"
|
|
2
|
+
#include "declaration.h"
|
|
2
3
|
#include "graph.h"
|
|
3
4
|
#include "handle.h"
|
|
4
5
|
#include "location.h"
|
|
@@ -6,6 +7,8 @@
|
|
|
6
7
|
|
|
7
8
|
VALUE cReference;
|
|
8
9
|
VALUE cConstantReference;
|
|
10
|
+
VALUE cUnresolvedConstantReference;
|
|
11
|
+
VALUE cResolvedConstantReference;
|
|
9
12
|
VALUE cMethodReference;
|
|
10
13
|
|
|
11
14
|
// ConstantReference#name -> String
|
|
@@ -72,16 +75,24 @@ static VALUE rdxr_method_reference_location(VALUE self) {
|
|
|
72
75
|
return location;
|
|
73
76
|
}
|
|
74
77
|
|
|
75
|
-
//
|
|
76
|
-
VALUE
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
// ResolvedConstantReference#declaration -> Declaration
|
|
79
|
+
static VALUE rdxr_resolved_constant_reference_declaration(VALUE self) {
|
|
80
|
+
HandleData *data;
|
|
81
|
+
TypedData_Get_Struct(self, HandleData, &handle_type, data);
|
|
82
|
+
|
|
83
|
+
void *graph;
|
|
84
|
+
TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
|
|
85
|
+
|
|
86
|
+
const struct CDeclaration *decl = rdx_resolved_constant_reference_declaration(graph, data->id);
|
|
87
|
+
if (decl == NULL) {
|
|
88
|
+
rb_raise(rb_eRuntimeError, "Invalid declaration for a resolved constant reference");
|
|
84
89
|
}
|
|
90
|
+
|
|
91
|
+
VALUE decl_class = rdxi_declaration_class_for_kind(decl->kind);
|
|
92
|
+
VALUE argv[] = {data->graph_obj, ULL2NUM(decl->id)};
|
|
93
|
+
free_c_declaration(decl);
|
|
94
|
+
|
|
95
|
+
return rb_class_new_instance(2, argv, decl_class);
|
|
85
96
|
}
|
|
86
97
|
|
|
87
98
|
void rdxi_initialize_reference(VALUE mRubydex) {
|
|
@@ -93,8 +104,16 @@ void rdxi_initialize_reference(VALUE mRubydex) {
|
|
|
93
104
|
cConstantReference = rb_define_class_under(mRubydex, "ConstantReference", cReference);
|
|
94
105
|
rb_define_alloc_func(cConstantReference, rdxr_handle_alloc);
|
|
95
106
|
rb_define_method(cConstantReference, "initialize", rdxr_handle_initialize, 2);
|
|
96
|
-
rb_define_method(cConstantReference, "name", rdxr_constant_reference_name, 0);
|
|
97
107
|
rb_define_method(cConstantReference, "location", rdxr_constant_reference_location, 0);
|
|
108
|
+
rb_funcall(rb_singleton_class(cConstantReference), rb_intern("private"), 1, ID2SYM(rb_intern("new")));
|
|
109
|
+
|
|
110
|
+
cUnresolvedConstantReference = rb_define_class_under(mRubydex, "UnresolvedConstantReference", cConstantReference);
|
|
111
|
+
rb_define_alloc_func(cUnresolvedConstantReference, rdxr_handle_alloc);
|
|
112
|
+
rb_define_method(cUnresolvedConstantReference, "name", rdxr_constant_reference_name, 0);
|
|
113
|
+
|
|
114
|
+
cResolvedConstantReference = rb_define_class_under(mRubydex, "ResolvedConstantReference", cConstantReference);
|
|
115
|
+
rb_define_alloc_func(cResolvedConstantReference, rdxr_handle_alloc);
|
|
116
|
+
rb_define_method(cResolvedConstantReference, "declaration", rdxr_resolved_constant_reference_declaration, 0);
|
|
98
117
|
|
|
99
118
|
cMethodReference = rb_define_class_under(mRubydex, "MethodReference", cReference);
|
|
100
119
|
rb_define_alloc_func(cMethodReference, rdxr_handle_alloc);
|
data/ext/rubydex/reference.h
CHANGED
|
@@ -6,11 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
extern VALUE cReference;
|
|
8
8
|
extern VALUE cConstantReference;
|
|
9
|
+
extern VALUE cUnresolvedConstantReference;
|
|
10
|
+
extern VALUE cResolvedConstantReference;
|
|
9
11
|
extern VALUE cMethodReference;
|
|
10
12
|
|
|
11
13
|
void rdxi_initialize_reference(VALUE mRubydex);
|
|
12
14
|
|
|
13
|
-
// Returns the Ruby class for a given UnresolvedReferenceKind without calling back into Rust
|
|
14
|
-
VALUE rdxi_reference_class_for_kind(ReferenceKind kind);
|
|
15
|
-
|
|
16
15
|
#endif // RUBYDEX_REFERENCE_H
|