rubydex 0.1.0.beta12-aarch64-linux

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +23 -0
  3. data/README.md +125 -0
  4. data/THIRD_PARTY_LICENSES.html +4562 -0
  5. data/exe/rdx +47 -0
  6. data/ext/rubydex/declaration.c +453 -0
  7. data/ext/rubydex/declaration.h +23 -0
  8. data/ext/rubydex/definition.c +284 -0
  9. data/ext/rubydex/definition.h +28 -0
  10. data/ext/rubydex/diagnostic.c +6 -0
  11. data/ext/rubydex/diagnostic.h +11 -0
  12. data/ext/rubydex/document.c +97 -0
  13. data/ext/rubydex/document.h +10 -0
  14. data/ext/rubydex/extconf.rb +138 -0
  15. data/ext/rubydex/graph.c +681 -0
  16. data/ext/rubydex/graph.h +10 -0
  17. data/ext/rubydex/handle.h +44 -0
  18. data/ext/rubydex/location.c +22 -0
  19. data/ext/rubydex/location.h +15 -0
  20. data/ext/rubydex/reference.c +123 -0
  21. data/ext/rubydex/reference.h +15 -0
  22. data/ext/rubydex/rubydex.c +22 -0
  23. data/ext/rubydex/utils.c +108 -0
  24. data/ext/rubydex/utils.h +34 -0
  25. data/lib/rubydex/3.2/rubydex.so +0 -0
  26. data/lib/rubydex/3.3/rubydex.so +0 -0
  27. data/lib/rubydex/3.4/rubydex.so +0 -0
  28. data/lib/rubydex/4.0/rubydex.so +0 -0
  29. data/lib/rubydex/comment.rb +17 -0
  30. data/lib/rubydex/diagnostic.rb +21 -0
  31. data/lib/rubydex/failures.rb +15 -0
  32. data/lib/rubydex/graph.rb +98 -0
  33. data/lib/rubydex/keyword.rb +17 -0
  34. data/lib/rubydex/keyword_parameter.rb +13 -0
  35. data/lib/rubydex/librubydex_sys.so +0 -0
  36. data/lib/rubydex/location.rb +90 -0
  37. data/lib/rubydex/mixin.rb +22 -0
  38. data/lib/rubydex/version.rb +5 -0
  39. data/lib/rubydex.rb +23 -0
  40. data/rbi/rubydex.rbi +422 -0
  41. data/rust/Cargo.lock +1851 -0
  42. data/rust/Cargo.toml +29 -0
  43. data/rust/about.hbs +78 -0
  44. data/rust/about.toml +10 -0
  45. data/rust/rubydex/Cargo.toml +42 -0
  46. data/rust/rubydex/src/compile_assertions.rs +13 -0
  47. data/rust/rubydex/src/diagnostic.rs +110 -0
  48. data/rust/rubydex/src/errors.rs +28 -0
  49. data/rust/rubydex/src/indexing/local_graph.rs +224 -0
  50. data/rust/rubydex/src/indexing/rbs_indexer.rs +1551 -0
  51. data/rust/rubydex/src/indexing/ruby_indexer.rs +2329 -0
  52. data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +4962 -0
  53. data/rust/rubydex/src/indexing.rs +210 -0
  54. data/rust/rubydex/src/integrity.rs +279 -0
  55. data/rust/rubydex/src/job_queue.rs +205 -0
  56. data/rust/rubydex/src/lib.rs +17 -0
  57. data/rust/rubydex/src/listing.rs +371 -0
  58. data/rust/rubydex/src/main.rs +160 -0
  59. data/rust/rubydex/src/model/built_in.rs +83 -0
  60. data/rust/rubydex/src/model/comment.rs +24 -0
  61. data/rust/rubydex/src/model/declaration.rs +671 -0
  62. data/rust/rubydex/src/model/definitions.rs +1682 -0
  63. data/rust/rubydex/src/model/document.rs +222 -0
  64. data/rust/rubydex/src/model/encoding.rs +22 -0
  65. data/rust/rubydex/src/model/graph.rs +3754 -0
  66. data/rust/rubydex/src/model/id.rs +110 -0
  67. data/rust/rubydex/src/model/identity_maps.rs +58 -0
  68. data/rust/rubydex/src/model/ids.rs +60 -0
  69. data/rust/rubydex/src/model/keywords.rs +256 -0
  70. data/rust/rubydex/src/model/name.rs +298 -0
  71. data/rust/rubydex/src/model/references.rs +111 -0
  72. data/rust/rubydex/src/model/string_ref.rs +50 -0
  73. data/rust/rubydex/src/model/visibility.rs +41 -0
  74. data/rust/rubydex/src/model.rs +15 -0
  75. data/rust/rubydex/src/offset.rs +147 -0
  76. data/rust/rubydex/src/position.rs +6 -0
  77. data/rust/rubydex/src/query.rs +1841 -0
  78. data/rust/rubydex/src/resolution.rs +6517 -0
  79. data/rust/rubydex/src/stats/memory.rs +71 -0
  80. data/rust/rubydex/src/stats/orphan_report.rs +264 -0
  81. data/rust/rubydex/src/stats/timer.rs +127 -0
  82. data/rust/rubydex/src/stats.rs +11 -0
  83. data/rust/rubydex/src/test_utils/context.rs +226 -0
  84. data/rust/rubydex/src/test_utils/graph_test.rs +730 -0
  85. data/rust/rubydex/src/test_utils/local_graph_test.rs +602 -0
  86. data/rust/rubydex/src/test_utils.rs +52 -0
  87. data/rust/rubydex/src/visualization/dot.rs +192 -0
  88. data/rust/rubydex/src/visualization.rs +6 -0
  89. data/rust/rubydex/tests/cli.rs +185 -0
  90. data/rust/rubydex-mcp/Cargo.toml +28 -0
  91. data/rust/rubydex-mcp/src/main.rs +48 -0
  92. data/rust/rubydex-mcp/src/server.rs +1145 -0
  93. data/rust/rubydex-mcp/src/tools.rs +49 -0
  94. data/rust/rubydex-mcp/tests/mcp.rs +302 -0
  95. data/rust/rubydex-sys/Cargo.toml +20 -0
  96. data/rust/rubydex-sys/build.rs +14 -0
  97. data/rust/rubydex-sys/cbindgen.toml +12 -0
  98. data/rust/rubydex-sys/src/declaration_api.rs +485 -0
  99. data/rust/rubydex-sys/src/definition_api.rs +443 -0
  100. data/rust/rubydex-sys/src/diagnostic_api.rs +99 -0
  101. data/rust/rubydex-sys/src/document_api.rs +85 -0
  102. data/rust/rubydex-sys/src/graph_api.rs +948 -0
  103. data/rust/rubydex-sys/src/lib.rs +79 -0
  104. data/rust/rubydex-sys/src/location_api.rs +79 -0
  105. data/rust/rubydex-sys/src/name_api.rs +135 -0
  106. data/rust/rubydex-sys/src/reference_api.rs +267 -0
  107. data/rust/rubydex-sys/src/utils.rs +70 -0
  108. data/rust/rustfmt.toml +2 -0
  109. metadata +159 -0
@@ -0,0 +1,44 @@
1
+ #ifndef RUBYDEX_HANDLE_H
2
+ #define RUBYDEX_HANDLE_H
3
+
4
+ #include "ruby.h"
5
+
6
+ typedef struct {
7
+ VALUE graph_obj; // Ruby Graph object to keep it alive
8
+ uint64_t id; // Canonical ID mapping to a DeclarationId, DefinitionId, UriId, etc. See `ids.rs`.
9
+ } HandleData;
10
+
11
+ static void handle_mark(void *ptr) {
12
+ if (ptr) {
13
+ HandleData *data = (HandleData *)ptr;
14
+ rb_gc_mark(data->graph_obj);
15
+ }
16
+ }
17
+
18
+ static void handle_free(void *ptr) {
19
+ if (ptr) {
20
+ xfree(ptr);
21
+ }
22
+ }
23
+
24
+ static const rb_data_type_t handle_type = {
25
+ "RubydexHandle", {handle_mark, handle_free, 0}, 0, 0, RUBY_TYPED_FREE_IMMEDIATELY};
26
+
27
+ static VALUE rdxr_handle_alloc(VALUE klass) {
28
+ HandleData *data = ALLOC(HandleData);
29
+ data->graph_obj = Qnil;
30
+ data->id = 0;
31
+
32
+ return TypedData_Wrap_Struct(klass, &handle_type, data);
33
+ }
34
+
35
+ static VALUE rdxr_handle_initialize(VALUE self, VALUE graph_obj, VALUE id_val) {
36
+ HandleData *data;
37
+ TypedData_Get_Struct(self, HandleData, &handle_type, data);
38
+ data->graph_obj = graph_obj;
39
+ data->id = NUM2ULL(id_val);
40
+
41
+ return self;
42
+ }
43
+
44
+ #endif // RUBYDEX_HANDLE_H
@@ -0,0 +1,22 @@
1
+ #include "location.h"
2
+
3
+ VALUE cLocation;
4
+
5
+ VALUE rdxi_build_location_value(Location *loc) {
6
+ if (loc == NULL) {
7
+ return Qnil;
8
+ }
9
+
10
+ VALUE uri = rb_utf8_str_new_cstr(loc->uri);
11
+
12
+ VALUE kwargs = rb_hash_new_capa(5);
13
+ rb_hash_aset(kwargs, ID2SYM(rb_intern("uri")), uri);
14
+ rb_hash_aset(kwargs, ID2SYM(rb_intern("start_line")), UINT2NUM(loc->start_line));
15
+ rb_hash_aset(kwargs, ID2SYM(rb_intern("end_line")), UINT2NUM(loc->end_line));
16
+ rb_hash_aset(kwargs, ID2SYM(rb_intern("start_column")), UINT2NUM(loc->start_column));
17
+ rb_hash_aset(kwargs, ID2SYM(rb_intern("end_column")), UINT2NUM(loc->end_column));
18
+
19
+ return rb_class_new_instance_kw(1, &kwargs, cLocation, RB_PASS_KEYWORDS);
20
+ }
21
+
22
+ void rdxi_initialize_location(VALUE mRubydex) { cLocation = rb_define_class_under(mRubydex, "Location", rb_cObject); }
@@ -0,0 +1,15 @@
1
+ #ifndef RUBYDEX_LOCATION_H
2
+ #define RUBYDEX_LOCATION_H
3
+
4
+ #include "ruby.h"
5
+ #include "rustbindings.h"
6
+
7
+ extern VALUE cLocation;
8
+
9
+ void rdxi_initialize_location(VALUE mRubydex);
10
+
11
+ // Helper to build a Ruby Rubydex::Location from a C Location pointer.
12
+ // Does not take ownership; caller remains responsible for freeing the C Location on the Rust side.
13
+ VALUE rdxi_build_location_value(Location *loc);
14
+
15
+ #endif // RUBYDEX_LOCATION_H
@@ -0,0 +1,123 @@
1
+ #include "reference.h"
2
+ #include "declaration.h"
3
+ #include "graph.h"
4
+ #include "handle.h"
5
+ #include "location.h"
6
+ #include "rustbindings.h"
7
+
8
+ VALUE cReference;
9
+ VALUE cConstantReference;
10
+ VALUE cUnresolvedConstantReference;
11
+ VALUE cResolvedConstantReference;
12
+ VALUE cMethodReference;
13
+
14
+ // ConstantReference#name -> String
15
+ static VALUE rdxr_constant_reference_name(VALUE self) {
16
+ HandleData *data;
17
+ TypedData_Get_Struct(self, HandleData, &handle_type, data);
18
+
19
+ void *graph;
20
+ TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
21
+
22
+ const char *name = rdx_constant_reference_name(graph, data->id);
23
+ if (name == NULL) {
24
+ return Qnil;
25
+ }
26
+
27
+ VALUE str = rb_utf8_str_new_cstr(name);
28
+ free_c_string(name);
29
+ return str;
30
+ }
31
+
32
+ // ConstantReference#location -> Rubydex::Location
33
+ static VALUE rdxr_constant_reference_location(VALUE self) {
34
+ HandleData *data;
35
+ TypedData_Get_Struct(self, HandleData, &handle_type, data);
36
+
37
+ void *graph;
38
+ TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
39
+
40
+ Location *loc = rdx_constant_reference_location(graph, data->id);
41
+ VALUE location = rdxi_build_location_value(loc);
42
+ rdx_location_free(loc);
43
+ return location;
44
+ }
45
+
46
+ // MethodReference#name -> String
47
+ static VALUE rdxr_method_reference_name(VALUE self) {
48
+ HandleData *data;
49
+ TypedData_Get_Struct(self, HandleData, &handle_type, data);
50
+
51
+ void *graph;
52
+ TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
53
+
54
+ const char *name = rdx_method_reference_name(graph, data->id);
55
+ if (name == NULL) {
56
+ return Qnil;
57
+ }
58
+
59
+ VALUE str = rb_utf8_str_new_cstr(name);
60
+ free_c_string(name);
61
+ return str;
62
+ }
63
+
64
+ // MethodReference#location -> Rubydex::Location
65
+ static VALUE rdxr_method_reference_location(VALUE self) {
66
+ HandleData *data;
67
+ TypedData_Get_Struct(self, HandleData, &handle_type, data);
68
+
69
+ void *graph;
70
+ TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
71
+
72
+ Location *loc = rdx_method_reference_location(graph, data->id);
73
+ VALUE location = rdxi_build_location_value(loc);
74
+ rdx_location_free(loc);
75
+ return location;
76
+ }
77
+
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");
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);
96
+ }
97
+
98
+ void rdxi_initialize_reference(VALUE mRubydex) {
99
+ cReference = rb_define_class_under(mRubydex, "Reference", rb_cObject);
100
+ rb_define_alloc_func(cReference, rdxr_handle_alloc);
101
+ rb_define_method(cReference, "initialize", rdxr_handle_initialize, 2);
102
+ rb_funcall(rb_singleton_class(cReference), rb_intern("private"), 1, ID2SYM(rb_intern("new")));
103
+
104
+ cConstantReference = rb_define_class_under(mRubydex, "ConstantReference", cReference);
105
+ rb_define_alloc_func(cConstantReference, rdxr_handle_alloc);
106
+ rb_define_method(cConstantReference, "initialize", rdxr_handle_initialize, 2);
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);
117
+
118
+ cMethodReference = rb_define_class_under(mRubydex, "MethodReference", cReference);
119
+ rb_define_alloc_func(cMethodReference, rdxr_handle_alloc);
120
+ rb_define_method(cMethodReference, "initialize", rdxr_handle_initialize, 2);
121
+ rb_define_method(cMethodReference, "name", rdxr_method_reference_name, 0);
122
+ rb_define_method(cMethodReference, "location", rdxr_method_reference_location, 0);
123
+ }
@@ -0,0 +1,15 @@
1
+ #ifndef RUBYDEX_REFERENCE_H
2
+ #define RUBYDEX_REFERENCE_H
3
+
4
+ #include "ruby.h"
5
+ #include "rustbindings.h"
6
+
7
+ extern VALUE cReference;
8
+ extern VALUE cConstantReference;
9
+ extern VALUE cUnresolvedConstantReference;
10
+ extern VALUE cResolvedConstantReference;
11
+ extern VALUE cMethodReference;
12
+
13
+ void rdxi_initialize_reference(VALUE mRubydex);
14
+
15
+ #endif // RUBYDEX_REFERENCE_H
@@ -0,0 +1,22 @@
1
+ #include "declaration.h"
2
+ #include "definition.h"
3
+ #include "diagnostic.h"
4
+ #include "document.h"
5
+ #include "graph.h"
6
+ #include "location.h"
7
+ #include "reference.h"
8
+
9
+ VALUE mRubydex;
10
+
11
+ void Init_rubydex(void) {
12
+ rb_ext_ractor_safe(true);
13
+
14
+ mRubydex = rb_define_module("Rubydex");
15
+ rdxi_initialize_graph(mRubydex);
16
+ rdxi_initialize_declaration(mRubydex);
17
+ rdxi_initialize_document(mRubydex);
18
+ rdxi_initialize_definition(mRubydex);
19
+ rdxi_initialize_location(mRubydex);
20
+ rdxi_initialize_diagnostic(mRubydex);
21
+ rdxi_initialize_reference(mRubydex);
22
+ }
@@ -0,0 +1,108 @@
1
+ #include "utils.h"
2
+ #include "declaration.h"
3
+ #include "reference.h"
4
+ #include "rustbindings.h"
5
+
6
+ // Convert a Ruby array of strings into a double char pointer so that we can pass that to Rust.
7
+ // This copies the data so it must be freed
8
+ char **rdxi_str_array_to_char(VALUE array, size_t length) {
9
+ char **converted_array = malloc(length * sizeof(char *));
10
+
11
+ for (size_t i = 0; i < length; i++) {
12
+ VALUE item = rb_ary_entry(array, i);
13
+ const char *string = StringValueCStr(item);
14
+
15
+ converted_array[i] = malloc(strlen(string) + 1);
16
+ strcpy(converted_array[i], string);
17
+ }
18
+
19
+ return converted_array;
20
+ }
21
+
22
+ // Free a char** array allocated by rdxi_str_array_to_char
23
+ void rdxi_free_str_array(char **array, size_t length) {
24
+ if (array != NULL) {
25
+ for (size_t i = 0; i < length; i++) {
26
+ free(array[i]);
27
+ }
28
+ free(array);
29
+ }
30
+ }
31
+
32
+ // Verify that the Ruby object is an array of strings or raise `TypeError`
33
+ void rdxi_check_array_of_strings(VALUE array) {
34
+ Check_Type(array, T_ARRAY);
35
+
36
+ for (long i = 0; i < RARRAY_LEN(array); i++) {
37
+ VALUE item = rb_ary_entry(array, i);
38
+ Check_Type(item, T_STRING);
39
+ }
40
+ }
41
+
42
+ // Yield body for iterating over declarations
43
+ VALUE rdxi_declarations_yield(VALUE args) {
44
+ VALUE self = rb_ary_entry(args, 0);
45
+ void *iter = (void *)(uintptr_t)NUM2ULL(rb_ary_entry(args, 1));
46
+
47
+ CDeclaration decl;
48
+ while (rdx_graph_declarations_iter_next(iter, &decl)) {
49
+ VALUE decl_class = rdxi_declaration_class_for_kind(decl.kind);
50
+ VALUE argv[] = {self, ULL2NUM(decl.id)};
51
+ VALUE handle = rb_class_new_instance(2, argv, decl_class);
52
+ rb_yield(handle);
53
+ }
54
+
55
+ return Qnil;
56
+ }
57
+
58
+ // Ensure function for iterating over declarations to always free the iterator
59
+ VALUE rdxi_declarations_ensure(VALUE args) {
60
+ void *iter = (void *)(uintptr_t)NUM2ULL(rb_ary_entry(args, 1));
61
+ rdx_graph_declarations_iter_free(iter);
62
+ return Qnil;
63
+ }
64
+
65
+ // Yield body for iterating over constant references
66
+ VALUE rdxi_constant_references_yield(VALUE args) {
67
+ VALUE graph_obj = rb_ary_entry(args, 0);
68
+ void *iter = (void *)(uintptr_t)NUM2ULL(rb_ary_entry(args, 1));
69
+
70
+ CConstantReference cref;
71
+ while (rdx_constant_references_iter_next(iter, &cref)) {
72
+ VALUE ref_class = (cref.declaration_id == 0)
73
+ ? cUnresolvedConstantReference
74
+ : cResolvedConstantReference;
75
+ VALUE argv[] = {graph_obj, ULL2NUM(cref.id)};
76
+ VALUE obj = rb_class_new_instance(2, argv, ref_class);
77
+ rb_yield(obj);
78
+ }
79
+ return Qnil;
80
+ }
81
+
82
+ // Ensure function for iterating over constant references to always free the iterator
83
+ VALUE rdxi_constant_references_ensure(VALUE args) {
84
+ void *iter = (void *)(uintptr_t)NUM2ULL(rb_ary_entry(args, 1));
85
+ rdx_constant_references_iter_free(iter);
86
+ return Qnil;
87
+ }
88
+
89
+ // Yield body for iterating over method references
90
+ VALUE rdxi_method_references_yield(VALUE args) {
91
+ VALUE graph_obj = rb_ary_entry(args, 0);
92
+ void *iter = (void *)(uintptr_t)NUM2ULL(rb_ary_entry(args, 1));
93
+
94
+ CMethodReference cref;
95
+ while (rdx_method_references_iter_next(iter, &cref)) {
96
+ VALUE argv[] = {graph_obj, ULL2NUM(cref.id)};
97
+ VALUE obj = rb_class_new_instance(2, argv, cMethodReference);
98
+ rb_yield(obj);
99
+ }
100
+ return Qnil;
101
+ }
102
+
103
+ // Ensure function for iterating over method references to always free the iterator
104
+ VALUE rdxi_method_references_ensure(VALUE args) {
105
+ void *iter = (void *)(uintptr_t)NUM2ULL(rb_ary_entry(args, 1));
106
+ rdx_method_references_iter_free(iter);
107
+ return Qnil;
108
+ }
@@ -0,0 +1,34 @@
1
+ #ifndef RUBYDEX_UTILS_H
2
+ #define RUBYDEX_UTILS_H
3
+
4
+ #include "ruby.h"
5
+
6
+ // Convert a Ruby array of strings into a double char pointer so that we can pass that to Rust.
7
+ // This copies the data so it must be freed with rdxi_free_str_array
8
+ char **rdxi_str_array_to_char(VALUE array, size_t length);
9
+
10
+ // Free a char** array allocated by rdxi_str_array_to_char
11
+ void rdxi_free_str_array(char **array, size_t length);
12
+
13
+ // Verify that the Ruby object is an array of strings or raise `TypeError`
14
+ void rdxi_check_array_of_strings(VALUE array);
15
+
16
+ // Yield body for iterating over declarations
17
+ VALUE rdxi_declarations_yield(VALUE args);
18
+
19
+ // Ensure function for iterating over declarations to always free the iterator
20
+ VALUE rdxi_declarations_ensure(VALUE args);
21
+
22
+ // Yield body for iterating over constant references
23
+ VALUE rdxi_constant_references_yield(VALUE args);
24
+
25
+ // Ensure function for iterating over constant references
26
+ VALUE rdxi_constant_references_ensure(VALUE args);
27
+
28
+ // Yield body for iterating over method references
29
+ VALUE rdxi_method_references_yield(VALUE args);
30
+
31
+ // Ensure function for iterating over method references
32
+ VALUE rdxi_method_references_ensure(VALUE args);
33
+
34
+ #endif // RUBYDEX_UTILS_H
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubydex
4
+ class Comment
5
+ #: String
6
+ attr_reader :string
7
+
8
+ #: Location
9
+ attr_reader :location
10
+
11
+ #: (?string: String, ?location: Location) -> void
12
+ def initialize(string:, location:)
13
+ @string = string
14
+ @location = location
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubydex
4
+ class Diagnostic
5
+ #: Symbol
6
+ attr_reader :rule
7
+
8
+ #: String
9
+ attr_reader :message
10
+
11
+ #: Location
12
+ attr_reader :location
13
+
14
+ #: (rule: Symbol, message: String, location: Location) -> void
15
+ def initialize(rule:, message:, location:)
16
+ @rule = rule
17
+ @message = message
18
+ @location = location
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubydex
4
+ class Failure
5
+ #: String
6
+ attr_reader :message
7
+
8
+ #: (String) -> void
9
+ def initialize(message)
10
+ @message = message
11
+ end
12
+ end
13
+
14
+ class IntegrityFailure < Failure; end
15
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubydex
4
+ # The global graph representing all declarations and their relationships for the workspace
5
+ #
6
+ # Note: this class is partially defined in C to integrate with the Rust backend
7
+ class Graph
8
+ IGNORED_DIRECTORIES = [
9
+ ".bundle",
10
+ ".claude",
11
+ ".git",
12
+ ".github",
13
+ ".ruby-lsp",
14
+ ".vscode",
15
+ "log",
16
+ "node_modules",
17
+ "tmp",
18
+ ].freeze
19
+
20
+ #: String
21
+ attr_accessor :workspace_path
22
+
23
+ #: (?workspace_path: String) -> void
24
+ def initialize(workspace_path: Dir.pwd)
25
+ @workspace_path = workspace_path
26
+
27
+ exclude_paths(IGNORED_DIRECTORIES.map { |dir| File.join(@workspace_path, dir) })
28
+ end
29
+
30
+ # Index all files and dependencies of the workspace that exists in `@workspace_path`
31
+ #: -> Array[String]
32
+ def index_workspace
33
+ index_all(workspace_paths)
34
+ end
35
+
36
+ # Returns all workspace paths that should be indexed, excluding directories that we don't need to descend into such
37
+ # as `.git`, `node_modules`. Also includes any top level Ruby files
38
+ #
39
+ #: -> Array[String]
40
+ def workspace_paths
41
+ paths = []
42
+
43
+ Dir.each_child(@workspace_path) do |entry|
44
+ full_path = File.join(@workspace_path, entry)
45
+
46
+ if File.directory?(full_path)
47
+ paths << full_path unless IGNORED_DIRECTORIES.include?(entry)
48
+ elsif File.extname(entry) == ".rb"
49
+ paths << full_path
50
+ end
51
+ end
52
+
53
+ add_workspace_dependency_paths(paths)
54
+ add_core_rbs_definition_paths(paths)
55
+ paths.uniq!
56
+ paths
57
+ end
58
+
59
+ private
60
+
61
+ # Gathers the paths we have to index for all workspace dependencies
62
+ #: (Array[String]) -> void
63
+ def add_workspace_dependency_paths(paths)
64
+ specs = Bundler.locked_gems&.specs
65
+ return unless specs
66
+
67
+ specs.each do |lazy_spec|
68
+ spec = Gem::Specification.find_by_name(lazy_spec.name)
69
+ spec.require_paths.each do |path|
70
+ # For native extensions, RubyGems inserts an absolute require path pointing to
71
+ # `gems/some-gem-1.0.0/extensions`. Those paths don't actually include any Ruby files inside, so we can skip
72
+ # descending them
73
+ next if File.absolute_path?(path)
74
+
75
+ paths << File.join(spec.full_gem_path, path)
76
+ end
77
+ rescue Gem::MissingSpecError
78
+ nil
79
+ end
80
+ end
81
+
82
+ # Searches for the latest installation of the `rbs` gem and adds the paths for the core and stdlib RBS definitions
83
+ # to the list of paths. This method does not require `rbs` to be a part of the bundle. It searches for whatever
84
+ # latest installation of `rbs` exists in the system and fails silently if we can't find one
85
+ #
86
+ #: (Array[String]) -> void
87
+ def add_core_rbs_definition_paths(paths)
88
+ rbs_gem_path = Gem.path
89
+ .flat_map { |path| Dir.glob(File.join(path, "gems", "rbs-[0-9]*/")) }
90
+ .max_by { |path| Gem::Version.new(File.basename(path).delete_prefix("rbs-")) }
91
+
92
+ return unless rbs_gem_path
93
+
94
+ paths << File.join(rbs_gem_path, "core")
95
+ paths << File.join(rbs_gem_path, "stdlib")
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubydex
4
+ class Keyword
5
+ #: String
6
+ attr_reader :name
7
+
8
+ #: String
9
+ attr_reader :documentation
10
+
11
+ #: (String name, String documentation) -> void
12
+ def initialize(name, documentation)
13
+ @name = name
14
+ @documentation = documentation
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubydex
4
+ class KeywordParameter
5
+ #: String
6
+ attr_reader :name
7
+
8
+ #: (String name) -> void
9
+ def initialize(name)
10
+ @name = name
11
+ end
12
+ end
13
+ end
Binary file
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubydex
4
+ # A zero based internal location. Intended to be used for tool-to-tool communication, such as a language server
5
+ # communicating with an editor.
6
+ class Location
7
+ class NotFileUriError < StandardError; end
8
+
9
+ include Comparable
10
+
11
+ #: String
12
+ attr_reader :uri
13
+
14
+ #: Integer
15
+ attr_reader :start_line, :end_line, :start_column, :end_column
16
+
17
+ #: (?uri: String, ?start_line: Integer, ?end_line: Integer, ?start_column: Integer, ?end_column: Integer) -> void
18
+ def initialize(uri:, start_line:, end_line:, start_column:, end_column:)
19
+ @uri = uri
20
+ @start_line = start_line
21
+ @end_line = end_line
22
+ @start_column = start_column
23
+ @end_column = end_column
24
+ end
25
+
26
+ #: () -> String
27
+ def to_file_path
28
+ uri = URI(@uri)
29
+ raise NotFileUriError, "URI is not a file:// URI: #{@uri}" unless uri.scheme == "file"
30
+
31
+ path = uri.path
32
+ # TODO: This has to go away once we have a proper URI abstraction
33
+ path.delete_prefix!("/") if Gem.win_platform?
34
+ path
35
+ end
36
+
37
+ #: (other: BasicObject) -> Integer
38
+ def <=>(other)
39
+ return -1 unless other.is_a?(Location)
40
+
41
+ comparable_values <=> other.comparable_values
42
+ end
43
+
44
+ #: () -> [String, Integer, Integer, Integer, Integer]
45
+ def comparable_values
46
+ [@uri, @start_line, @start_column, @end_line, @end_column]
47
+ end
48
+
49
+ # Turns this zero based location into a one based location for display purposes.
50
+ #
51
+ #: () -> DisplayLocation
52
+ def to_display
53
+ DisplayLocation.new(
54
+ uri: @uri,
55
+ start_line: @start_line + 1,
56
+ end_line: @end_line + 1,
57
+ start_column: @start_column + 1,
58
+ end_column: @end_column + 1,
59
+ )
60
+ end
61
+
62
+ #: -> String
63
+ def to_s
64
+ "#{to_file_path}:#{@start_line + 1}:#{@start_column + 1}-#{@end_line + 1}:#{@end_column + 1}"
65
+ end
66
+ end
67
+
68
+ # A one based location intended for display purposes. This is what should be used when displaying a location to users,
69
+ # like in CLIs
70
+ class DisplayLocation < Location
71
+ # Returns itself
72
+ #
73
+ #: () -> DisplayLocation
74
+ def to_display
75
+ self
76
+ end
77
+
78
+ # Normalize to zero-based for comparison with Location
79
+ #
80
+ #: () -> [String, Integer, Integer, Integer, Integer]
81
+ def comparable_values
82
+ [@uri, @start_line - 1, @start_column - 1, @end_line - 1, @end_column - 1]
83
+ end
84
+
85
+ #: -> String
86
+ def to_s
87
+ "#{to_file_path}:#{@start_line}:#{@start_column}-#{@end_line}:#{@end_column}"
88
+ end
89
+ end
90
+ end