rubydex 0.3.0 → 0.4.1

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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +29 -7
  3. data/THIRD_PARTY_LICENSES.html +238 -2
  4. data/exe/rdx +2 -149
  5. data/ext/rubydex/config.c +140 -0
  6. data/ext/rubydex/config.h +16 -0
  7. data/ext/rubydex/definition.c +34 -0
  8. data/ext/rubydex/definition.h +3 -0
  9. data/ext/rubydex/diagnostic.c +28 -1
  10. data/ext/rubydex/diagnostic.h +2 -0
  11. data/ext/rubydex/extconf.rb +4 -2
  12. data/ext/rubydex/graph.c +71 -55
  13. data/ext/rubydex/graph.h +6 -0
  14. data/ext/rubydex/query.c +398 -16
  15. data/ext/rubydex/rubydex.c +2 -0
  16. data/ext/rubydex/utils.c +11 -4
  17. data/lib/ruby_lsp/rubydex/addon.rb +211 -0
  18. data/lib/rubydex/cli/command/console.rb +55 -0
  19. data/lib/rubydex/cli/command/lint/explain.rb +76 -0
  20. data/lib/rubydex/cli/command/lint.rb +208 -0
  21. data/lib/rubydex/cli/command/mcp.rb +30 -0
  22. data/lib/rubydex/cli/command/query.rb +70 -0
  23. data/lib/rubydex/cli/command/skill.rb +69 -0
  24. data/lib/rubydex/cli/command.rb +168 -0
  25. data/lib/rubydex/cli.rb +93 -0
  26. data/lib/rubydex/config.rb +59 -0
  27. data/lib/rubydex/diagnostic.rb +12 -3
  28. data/lib/rubydex/errors.rb +42 -1
  29. data/lib/rubydex/graph.rb +10 -3
  30. data/lib/rubydex/linter/custom_rule.rb +97 -0
  31. data/lib/rubydex/linter/helpers/path_helpers.rb +78 -0
  32. data/lib/rubydex/linter/helpers/source_access_helpers.rb +31 -0
  33. data/lib/rubydex/linter/rule_loader.rb +36 -0
  34. data/lib/rubydex/linter/rule_test_case.rb +343 -0
  35. data/lib/rubydex/linter/runner.rb +56 -0
  36. data/lib/rubydex/linter.rb +19 -0
  37. data/lib/rubydex/location.rb +3 -0
  38. data/lib/rubydex/mcp_server.rb +1 -2
  39. data/lib/rubydex/related_information.rb +17 -0
  40. data/lib/rubydex/rule.rb +33 -0
  41. data/lib/rubydex/rules/dynamic_ancestor.rb +29 -0
  42. data/lib/rubydex/rules/dynamic_constant_reference.rb +25 -0
  43. data/lib/rubydex/rules/dynamic_singleton_definition.rb +30 -0
  44. data/lib/rubydex/rules/invalid_constant_visibility.rb +28 -0
  45. data/lib/rubydex/rules/invalid_method_visibility.rb +28 -0
  46. data/lib/rubydex/rules/parse_error.rb +25 -0
  47. data/lib/rubydex/rules/parse_warning.rb +28 -0
  48. data/lib/rubydex/rules/top_level_mixin_self.rb +27 -0
  49. data/lib/rubydex/rules/undefined_constant_visibility_target.rb +27 -0
  50. data/lib/rubydex/rules/undefined_method_visibility_target.rb +27 -0
  51. data/lib/rubydex/severity.rb +70 -0
  52. data/lib/rubydex/skill.rb +89 -0
  53. data/lib/rubydex/skill_registry.rb +62 -0
  54. data/lib/rubydex/version.rb +1 -1
  55. data/lib/rubydex.rb +8 -0
  56. data/lib/rubydex_linter/rules/rule_structure.rb +140 -0
  57. data/rbi/rubydex.rbi +464 -21
  58. data/rust/Cargo.lock +2 -2
  59. data/rust/rubydex/Cargo.toml +5 -1
  60. data/rust/rubydex/benches/graph_memory.rs +3 -5
  61. data/rust/rubydex/src/bin/generate_ruby_rules.rs +94 -0
  62. data/rust/rubydex/src/config.rs +538 -157
  63. data/rust/rubydex/src/diagnostic.rs +162 -45
  64. data/rust/rubydex/src/errors.rs +0 -1
  65. data/rust/rubydex/src/indexing/local_graph.rs +6 -5
  66. data/rust/rubydex/src/indexing/rbs_indexer.rs +270 -6
  67. data/rust/rubydex/src/indexing/ruby_indexer.rs +10 -12
  68. data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +134 -81
  69. data/rust/rubydex/src/lib.rs +1 -0
  70. data/rust/rubydex/src/listing.rs +26 -1
  71. data/rust/rubydex/src/main.rs +7 -4
  72. data/rust/rubydex/src/model/declaration.rs +302 -219
  73. data/rust/rubydex/src/model/graph.rs +27 -40
  74. data/rust/rubydex/src/model/name.rs +58 -17
  75. data/rust/rubydex/src/operation/ruby_builder.rs +30 -45
  76. data/rust/rubydex/src/path_helpers.rs +77 -0
  77. data/rust/rubydex/src/query/cypher/schema.rs +63 -0
  78. data/rust/rubydex/src/query/cypher/tests.rs +26 -1
  79. data/rust/rubydex/src/query/cypher.rs +8 -11
  80. data/rust/rubydex/src/query.rs +314 -44
  81. data/rust/rubydex/src/resolution.rs +139 -187
  82. data/rust/rubydex/src/resolution_tests.rs +247 -19
  83. data/rust/rubydex/src/test_utils/context.rs +2 -1
  84. data/rust/rubydex/src/test_utils/graph_test.rs +26 -12
  85. data/rust/rubydex/src/test_utils/local_graph_test.rs +19 -0
  86. data/rust/rubydex/tests/cli.rs +4 -4
  87. data/rust/rubydex-sys/src/config_api.rs +205 -0
  88. data/rust/rubydex-sys/src/cypher_api.rs +791 -0
  89. data/rust/rubydex-sys/src/definition_api.rs +68 -1
  90. data/rust/rubydex-sys/src/diagnostic_api.rs +42 -8
  91. data/rust/rubydex-sys/src/graph_api.rs +125 -205
  92. data/rust/rubydex-sys/src/lib.rs +2 -0
  93. data/rust/rubydex-sys/src/name_api.rs +49 -17
  94. data/rust/rubydex-sys/src/utils.rs +37 -0
  95. data/skills/send-private-method/SKILL.md +133 -0
  96. metadata +42 -2
@@ -38,6 +38,17 @@ VALUE cClassVariableDefinition;
38
38
  VALUE cMethodAliasDefinition;
39
39
  VALUE cGlobalVariableAliasDefinition;
40
40
 
41
+ uint64_t rdxi_definition_id_for_graph(VALUE definition, VALUE graph_obj) {
42
+ HandleData *data;
43
+ TypedData_Get_Struct(definition, HandleData, &handle_type, data);
44
+
45
+ if (data->graph_obj != graph_obj) {
46
+ rb_raise(rb_eArgError, "definition must belong to this graph");
47
+ }
48
+
49
+ return data->id;
50
+ }
51
+
41
52
  // Keep this in sync with definition.rs
42
53
  VALUE rdxi_definition_class_for_kind(DefinitionKind kind) {
43
54
  switch (kind) {
@@ -153,6 +164,25 @@ static VALUE rdxr_definition_name(VALUE self) {
153
164
  return rdxi_owned_c_string_to_ruby(name);
154
165
  }
155
166
 
167
+ /*
168
+ * call-seq:
169
+ * raw_name -> String
170
+ *
171
+ * Returns the class, module, or constant name as written in source, preserving explicit parent scopes like "Foo::Bar"
172
+ * and rooted paths like "::Bar".
173
+ */
174
+ static VALUE rdxr_definition_raw_name(VALUE self) {
175
+ HandleData *data;
176
+ void *graph = rdxi_graph_from_handle(self, &data);
177
+
178
+ const char *name = rdx_definition_raw_name(graph, data->id);
179
+ if (name == NULL) {
180
+ rb_raise(rb_eRuntimeError, "Definition not found");
181
+ }
182
+
183
+ return rdxi_owned_c_string_to_ruby(name);
184
+ }
185
+
156
186
  /*
157
187
  * call-seq:
158
188
  * deprecated? -> bool
@@ -442,6 +472,7 @@ void rdxi_initialize_definition(VALUE mod) {
442
472
  rb_define_method(cDefinition, "document", rdxr_definition_document, 0);
443
473
 
444
474
  cClassDefinition = rb_define_class_under(mRubydex, "ClassDefinition", cDefinition);
475
+ rb_define_method(cClassDefinition, "raw_name", rdxr_definition_raw_name, 0);
445
476
  rb_define_method(cClassDefinition, "superclass", rdxr_class_definition_superclass, 0);
446
477
  rb_define_method(cClassDefinition, "mixins", rdxr_definition_mixins, 0);
447
478
 
@@ -449,10 +480,13 @@ void rdxi_initialize_definition(VALUE mod) {
449
480
  rb_define_method(cSingletonClassDefinition, "mixins", rdxr_definition_mixins, 0);
450
481
 
451
482
  cModuleDefinition = rb_define_class_under(mRubydex, "ModuleDefinition", cDefinition);
483
+ rb_define_method(cModuleDefinition, "raw_name", rdxr_definition_raw_name, 0);
452
484
  rb_define_method(cModuleDefinition, "mixins", rdxr_definition_mixins, 0);
453
485
 
454
486
  cConstantDefinition = rb_define_class_under(mRubydex, "ConstantDefinition", cDefinition);
487
+ rb_define_method(cConstantDefinition, "raw_name", rdxr_definition_raw_name, 0);
455
488
  cConstantAliasDefinition = rb_define_class_under(mRubydex, "ConstantAliasDefinition", cDefinition);
489
+ rb_define_method(cConstantAliasDefinition, "raw_name", rdxr_definition_raw_name, 0);
456
490
  cConstantVisibilityDefinition = rb_define_class_under(mRubydex, "ConstantVisibilityDefinition", cDefinition);
457
491
  cMethodVisibilityDefinition = rb_define_class_under(mRubydex, "MethodVisibilityDefinition", cDefinition);
458
492
  cMethodDefinition = rb_define_class_under(mRubydex, "MethodDefinition", cDefinition);
@@ -22,6 +22,9 @@ extern VALUE cGlobalVariableAliasDefinition;
22
22
 
23
23
  void rdxi_initialize_definition(VALUE mRubydex);
24
24
 
25
+ // Returns the definition ID after verifying that the definition belongs to `graph_obj`.
26
+ uint64_t rdxi_definition_id_for_graph(VALUE definition, VALUE graph_obj);
27
+
25
28
  // Returns the Ruby class for a given DefinitionKind without calling back into Rust
26
29
  VALUE rdxi_definition_class_for_kind(DefinitionKind kind);
27
30
 
@@ -6,6 +6,33 @@
6
6
  * mRubydex = rb_define_module("Rubydex")
7
7
  */
8
8
 
9
+ static VALUE mRules;
9
10
  VALUE cDiagnostic;
10
11
 
11
- void rdxi_initialize_diagnostic(VALUE mRubydex) { cDiagnostic = rb_define_class_under(mRubydex, "Diagnostic", rb_cObject); }
12
+ VALUE rdxi_build_diagnostic_severity_value(VALUE mRubydex, DiagnosticSeverity severity) {
13
+ VALUE mSeverity = rb_const_get(mRubydex, rb_intern("Severity"));
14
+
15
+ switch (severity) {
16
+ case DiagnosticSeverity_Error:
17
+ return rb_const_get(mSeverity, rb_intern("Error"));
18
+ case DiagnosticSeverity_Warning:
19
+ return rb_const_get(mSeverity, rb_intern("Warning"));
20
+ case DiagnosticSeverity_Information:
21
+ return rb_const_get(mSeverity, rb_intern("Information"));
22
+ case DiagnosticSeverity_Hint:
23
+ return rb_const_get(mSeverity, rb_intern("Hint"));
24
+ default:
25
+ rb_raise(rb_eRuntimeError, "Unknown DiagnosticSeverity: %d", severity);
26
+ }
27
+
28
+ return Qnil;
29
+ }
30
+
31
+ VALUE rdxi_rule_class_from_name(const char *name, size_t length) {
32
+ return rb_const_get_at(mRules, rb_intern2(name, (long)length));
33
+ }
34
+
35
+ void rdxi_initialize_diagnostic(VALUE moduleRubydex) {
36
+ cDiagnostic = rb_define_class_under(moduleRubydex, "Diagnostic", rb_cObject);
37
+ mRules = rb_define_module_under(moduleRubydex, "Rules");
38
+ }
@@ -7,5 +7,7 @@
7
7
  extern VALUE cDiagnostic;
8
8
 
9
9
  void rdxi_initialize_diagnostic(VALUE mRubydex);
10
+ VALUE rdxi_build_diagnostic_severity_value(VALUE mRubydex, DiagnosticSeverity severity);
11
+ VALUE rdxi_rule_class_from_name(const char *name, size_t length);
10
12
 
11
13
  #endif // RUBYDEX_DIAGNOSTIC_H
@@ -23,12 +23,12 @@ release = ENV["RELEASE"] || !developing_rubydex
23
23
  root_dir = gem_dir.join("rust")
24
24
  target_dir = root_dir.join("target")
25
25
  target_dir = target_dir.join("x86_64-pc-windows-gnu") if Gem.win_platform?
26
- target_dir = target_dir.join(release ? "release" : "debug")
26
+ target_dir = target_dir.join("$(RUST_PROFILE)")
27
27
 
28
28
  bindings_path = root_dir.join("rubydex-sys").join("rustbindings.h")
29
29
 
30
30
  cargo_args = ["--manifest-path #{root_dir.join("Cargo.toml")}"]
31
- cargo_args << "--release" if release
31
+ cargo_args << "$(CARGO_PROFILE_FLAG)"
32
32
 
33
33
  if Gem.win_platform?
34
34
  cargo_args << "--target x86_64-pc-windows-gnu"
@@ -102,6 +102,8 @@ makefile = File.read("Makefile")
102
102
 
103
103
  new_makefile = makefile.gsub("$(OBJS): $(HDRS) $(ruby_headers)", <<~MAKEFILE.chomp)
104
104
  .PHONY: compile_rust
105
+ RUST_PROFILE = $(if $(strip $(RELEASE)),release,#{developing_rubydex ? "debug" : "release"})
106
+ CARGO_PROFILE_FLAG = $(if $(filter release,$(RUST_PROFILE)),--release)
105
107
  RUST_SRCS = #{File.expand_path("Cargo.toml", root_dir)} #{File.expand_path("Cargo.lock", root_dir)} #{rust_srcs.join(" ")}
106
108
 
107
109
  .rust_built: $(RUST_SRCS)
data/ext/rubydex/graph.c CHANGED
@@ -1,5 +1,7 @@
1
1
  #include "graph.h"
2
+ #include "config.h"
2
3
  #include "declaration.h"
4
+ #include "definition.h"
3
5
  #include "diagnostic.h"
4
6
  #include "document.h"
5
7
  #include "location.h"
@@ -255,6 +257,30 @@ static VALUE rdxr_graph_fuzzy_search(int argc, VALUE *argv, VALUE self) {
255
257
  return rdxr_graph_yield_search_results(self, iter);
256
258
  }
257
259
 
260
+ /*
261
+ * call-seq:
262
+ * dead_code_candidates -> Enumerator[Rubydex::Declaration]
263
+ *
264
+ * Returns an enumerator over declarations that may be unused because the analysis could not find any references to
265
+ * them. This misses metaprogramming or untyped code, which is why the term candidates is used.
266
+ *
267
+ * Currently, only supports constants.
268
+ */
269
+ static VALUE rdxr_graph_dead_code_candidates(VALUE self) {
270
+ if (!rb_block_given_p()) {
271
+ return rb_enumeratorize(self, rb_str_new2("dead_code_candidates"), 0, NULL);
272
+ }
273
+
274
+ void *graph;
275
+ TypedData_Get_Struct(self, void *, &graph_type, graph);
276
+
277
+ void *iter = rdx_graph_dead_code_candidates(graph);
278
+ VALUE args = rb_ary_new_from_args(2, self, ULL2NUM((uintptr_t)iter));
279
+ rb_ensure(rdxi_declarations_yield, args, rdxi_declarations_ensure, args);
280
+
281
+ return self;
282
+ }
283
+
258
284
  // Body function for rb_ensure in Graph#documents
259
285
  static VALUE graph_documents_yield(VALUE args) {
260
286
  VALUE self = rb_ary_entry(args, 0);
@@ -485,25 +511,48 @@ static VALUE rdxr_graph_set_encoding(VALUE self, VALUE encoding) {
485
511
 
486
512
  /*
487
513
  * call-seq:
488
- * resolve_constant(name, nesting) -> Rubydex::Declaration?
514
+ * resolve_constant(name, context) -> Rubydex::Declaration?
489
515
  *
490
- * Runs the resolver on a single constant reference to determine what it points to.
516
+ * Runs the resolver on a single constant reference using an array of nesting names or a namespace definition as its
517
+ * context.
491
518
  */
492
- static VALUE rdxr_graph_resolve_constant(VALUE self, VALUE const_name, VALUE nesting) {
519
+ static VALUE rdxr_graph_resolve_constant(VALUE self, VALUE const_name, VALUE context) {
493
520
  Check_Type(const_name, T_STRING);
494
- rdxi_check_array_of_strings(nesting);
495
-
496
- // Convert the given file paths into a char** array, so that we can pass to Rust
497
- size_t length = RARRAY_LEN(nesting);
498
- char **converted_file_paths = rdxi_str_array_to_char(nesting, length);
521
+ const char *const_name_string = StringValueCStr(const_name);
499
522
 
500
523
  void *graph;
501
524
  TypedData_Get_Struct(self, void *, &graph_type, graph);
502
525
 
503
- const CDeclaration *decl =
504
- rdx_graph_resolve_constant(graph, StringValueCStr(const_name), (const char **)converted_file_paths, length);
526
+ const CDeclaration *decl;
527
+ if (RB_TYPE_P(context, T_ARRAY)) {
528
+ rdxi_check_array_of_strings(context);
529
+
530
+ size_t length = RARRAY_LEN(context);
531
+ char **converted_names = rdxi_str_array_to_char(context, length);
532
+ decl = rdx_graph_resolve_constant(graph, const_name_string, (const char **)converted_names, length);
533
+ rdxi_free_str_array(converted_names, length);
534
+ } else if (rb_obj_is_kind_of(context, cClassDefinition) ||
535
+ rb_obj_is_kind_of(context, cSingletonClassDefinition) ||
536
+ rb_obj_is_kind_of(context, cModuleDefinition)) {
537
+ uint64_t definition_id = rdxi_definition_id_for_graph(context, self);
538
+ CDefinitionConstantResolutionResult result =
539
+ rdx_graph_resolve_constant_from_definition(graph, const_name_string, definition_id);
540
+
541
+ if (result.status == CDefinitionConstantResolution_DefinitionNotFound) {
542
+ rb_raise(rb_eRuntimeError, "Definition not found");
543
+ }
544
+ if (result.status == CDefinitionConstantResolution_InvalidDefinitionKind) {
545
+ // This is unreachable because the rb_obj_is_kind_of checks above only accept supported definition kinds.
546
+ rb_raise(rb_eRuntimeError, "Unexpected definition kind");
547
+ }
505
548
 
506
- rdxi_free_str_array(converted_file_paths, length);
549
+ decl = result.declaration;
550
+ } else {
551
+ rb_raise(
552
+ rb_eTypeError,
553
+ "context must be an Array of Strings, ClassDefinition, SingletonClassDefinition, or ModuleDefinition"
554
+ );
555
+ }
507
556
 
508
557
  if (decl == NULL) {
509
558
  return Qnil;
@@ -631,7 +680,7 @@ static VALUE rdxr_graph_diagnostics(VALUE self) {
631
680
  for (size_t i = 0; i < array->len; i++) {
632
681
  DiagnosticEntry entry = array->items[i];
633
682
  VALUE message = entry.message == NULL ? Qnil : rb_utf8_str_new_cstr(entry.message);
634
- VALUE rule = rb_str_intern(rb_str_new2(entry.rule));
683
+ VALUE rule = rdxi_rule_class_from_name(entry.rule.name, entry.rule.name_length);
635
684
  VALUE location = rdxi_build_location_value(entry.location);
636
685
 
637
686
  VALUE kwargs = rb_hash_new();
@@ -787,6 +836,7 @@ static VALUE rdxr_graph_complete_method_argument(int argc, VALUE *argv, VALUE se
787
836
 
788
837
  Check_Type(name, T_STRING);
789
838
  rdxi_check_array_of_strings(nesting);
839
+ const char *name_string = StringValueCStr(name);
790
840
 
791
841
  const char *self_receiver = extract_self_receiver(opts);
792
842
 
@@ -797,7 +847,7 @@ static VALUE rdxr_graph_complete_method_argument(int argc, VALUE *argv, VALUE se
797
847
  char **converted_nesting = rdxi_str_array_to_char(nesting, nesting_count);
798
848
 
799
849
  struct CompletionResult result = rdx_graph_complete_method_argument(
800
- graph, StringValueCStr(name), (const char *const *)converted_nesting, nesting_count, self_receiver);
850
+ graph, name_string, (const char *const *)converted_nesting, nesting_count, self_receiver);
801
851
 
802
852
  rdxi_free_str_array(converted_nesting, nesting_count);
803
853
  return completion_result_to_ruby_array(result, self);
@@ -872,52 +922,18 @@ static VALUE rdxr_graph_workspace_path(VALUE self) {
872
922
 
873
923
  /*
874
924
  * call-seq:
875
- * workspace_path=(path) -> void
925
+ * load_config(config) -> void
876
926
  *
877
- * Sets the root directory of the workspace being indexed.
927
+ * Applies a parsed Rubydex::Config to the graph.
878
928
  */
879
- static VALUE rdxr_graph_set_workspace_path(VALUE self, VALUE path) {
880
- Check_Type(path, T_STRING);
881
-
882
- void *graph;
883
- TypedData_Get_Struct(self, void*, &graph_type, graph);
884
-
885
- rdx_graph_set_workspace_path(graph, StringValueCStr(path));
886
- return path;
887
- }
888
-
889
- /*
890
- * call-seq:
891
- * load_config(config_path = nil) -> void
892
- *
893
- * Loads a configuration file for the graph. If `config_path` is nil, loads the default configuration file at
894
- * `workspace_path/rubydex.toml` if it exists. Will raise on malformed files or if an explicit path is given but the
895
- * file does not exist.
896
- */
897
- static VALUE rdxr_graph_load_config(int argc, VALUE *argv, VALUE self) {
898
- VALUE config_path;
899
- rb_scan_args(argc, argv, "01", &config_path);
900
-
929
+ static VALUE rdxr_graph_load_config(VALUE self, VALUE config_obj) {
901
930
  void *graph;
902
931
  TypedData_Get_Struct(self, void *, &graph_type, graph);
903
932
 
904
- const char *config_path_cstr = NULL;
905
-
906
- if (!NIL_P(config_path)) {
907
- Check_Type(config_path, T_STRING);
908
- config_path_cstr = StringValueCStr(config_path);
909
- }
910
-
911
- const char *error = rdx_graph_load_config(graph, config_path_cstr);
912
- if (error == NULL) {
913
- return Qnil;
914
- }
933
+ void *config = rdxi_config_from_object(config_obj);
934
+ rdx_graph_load_config(graph, config);
915
935
 
916
- VALUE message = rb_utf8_str_new_cstr(error);
917
- free_c_string(error);
918
-
919
- VALUE config_error = rb_const_get(mRubydex, rb_intern("ConfigError"));
920
- rb_exc_raise(rb_exc_new_str(config_error, message));
936
+ return Qnil;
921
937
  }
922
938
 
923
939
  /*
@@ -969,6 +985,7 @@ void rdxi_initialize_graph(VALUE moduleRubydex) {
969
985
  rb_define_method(cGraph, "[]", rdxr_graph_aref, 1);
970
986
  rb_define_method(cGraph, "search", rdxr_graph_search, -1);
971
987
  rb_define_method(cGraph, "fuzzy_search", rdxr_graph_fuzzy_search, -1);
988
+ rb_define_method(cGraph, "dead_code_candidates", rdxr_graph_dead_code_candidates, 0);
972
989
  rb_define_method(cGraph, "encoding=", rdxr_graph_set_encoding, 1);
973
990
  rb_define_method(cGraph, "resolve_require_path", rdxr_graph_resolve_require_path, 2);
974
991
  rb_define_method(cGraph, "require_paths", rdxr_graph_require_paths, 1);
@@ -979,7 +996,6 @@ void rdxi_initialize_graph(VALUE moduleRubydex) {
979
996
  rb_define_method(cGraph, "exclude_patterns", rdxr_graph_exclude_patterns, 1);
980
997
  rb_define_method(cGraph, "excluded_patterns", rdxr_graph_excluded_patterns, 0);
981
998
  rb_define_method(cGraph, "workspace_path", rdxr_graph_workspace_path, 0);
982
- rb_define_method(cGraph, "workspace_path=", rdxr_graph_set_workspace_path, 1);
983
- rb_define_method(cGraph, "load_config", rdxr_graph_load_config, -1);
999
+ rb_define_method(cGraph, "load_config", rdxr_graph_load_config, 1);
984
1000
  rb_define_method(cGraph, "keyword", rdxr_graph_keyword, 1);
985
1001
  }
data/ext/rubydex/graph.h CHANGED
@@ -5,6 +5,12 @@
5
5
 
6
6
  extern const rb_data_type_t graph_type;
7
7
 
8
+ static inline void *rdxi_graph_from_object(VALUE graph_obj) {
9
+ void *graph;
10
+ TypedData_Get_Struct(graph_obj, void *, &graph_type, graph);
11
+ return graph;
12
+ }
13
+
8
14
  void rdxi_initialize_graph(VALUE mRubydex);
9
15
 
10
16
  #endif // RUBYDEX_GRAPH_H