rubydex 0.2.6 → 0.2.8

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.
data/ext/rubydex/graph.c CHANGED
@@ -8,6 +8,11 @@
8
8
  #include "rustbindings.h"
9
9
  #include "utils.h"
10
10
 
11
+ /*
12
+ * RDoc parser workaround for https://github.com/ruby/rdoc/issues/1744:
13
+ * mRubydex = rb_define_module("Rubydex")
14
+ */
15
+
11
16
  static VALUE cGraph;
12
17
  static VALUE mRubydex;
13
18
  static VALUE cKeyword;
@@ -68,8 +73,12 @@ static VALUE rdxr_graph_alloc(VALUE klass) {
68
73
  return TypedData_Wrap_Struct(klass, &graph_type, graph);
69
74
  }
70
75
 
71
- // Graph#index_all: (Array[String] file_paths) -> Array[String]
72
- // Returns an array of IO error messages encountered during indexing
76
+ /*
77
+ * call-seq:
78
+ * index_all(file_paths) -> Array[String]
79
+ *
80
+ * Returns an array of I/O error messages encountered during indexing.
81
+ */
73
82
  static VALUE rdxr_graph_index_all(VALUE self, VALUE file_paths) {
74
83
  rdxi_check_array_of_strings(file_paths);
75
84
 
@@ -99,9 +108,12 @@ static VALUE rdxr_graph_index_all(VALUE self, VALUE file_paths) {
99
108
  return array;
100
109
  }
101
110
 
102
- // Indexes a single source string in memory, dispatching to the appropriate indexer based on language_id
103
- //
104
- // Graph#index_source: (String uri, String source, String language_id) -> void
111
+ /*
112
+ * call-seq:
113
+ * index_source(uri, source, language_id) -> nil
114
+ *
115
+ * Indexes a single source string in memory, dispatching to the appropriate indexer based on language_id.
116
+ */
105
117
  static VALUE rdxr_graph_index_source(VALUE self, VALUE uri, VALUE source, VALUE language_id) {
106
118
  Check_Type(uri, T_STRING);
107
119
  Check_Type(source, T_STRING);
@@ -148,8 +160,12 @@ static VALUE graph_declarations_size(VALUE self, VALUE _args, VALUE _eobj) {
148
160
  return SIZET2NUM(len);
149
161
  }
150
162
 
151
- // Graph#declarations: () -> Enumerator[Declaration]
152
- // Returns an enumerator that yields all declarations lazily
163
+ /*
164
+ * call-seq:
165
+ * declarations -> Enumerator[Rubydex::Declaration]
166
+ *
167
+ * Returns an enumerator that yields all declarations lazily.
168
+ */
153
169
  static VALUE rdxr_graph_declarations(VALUE self) {
154
170
  if (!rb_block_given_p()) {
155
171
  return rb_enumeratorize_with_size(self, rb_str_new2("declarations"), 0, NULL, graph_declarations_size);
@@ -178,34 +194,56 @@ static VALUE rdxr_graph_yield_search_results(VALUE self, void *iter) {
178
194
  return self;
179
195
  }
180
196
 
181
- // Graph#search: (String query) -> Enumerator[Declaration]
182
- // Returns an enumerator that yields declarations matching the query exactly (substring match)
183
- static VALUE rdxr_graph_search(VALUE self, VALUE query) {
184
- Check_Type(query, T_STRING);
197
+ /*
198
+ * call-seq:
199
+ * search(*queries) -> Enumerator[Rubydex::Declaration]
200
+ *
201
+ * Returns an enumerator that yields declarations whose name matches any of the queries exactly by substring.
202
+ */
203
+ static VALUE rdxr_graph_search(int argc, VALUE *argv, VALUE self) {
204
+ rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
205
+ VALUE queries = rb_ary_new_from_values(argc, argv);
206
+ rdxi_check_array_of_strings(queries);
185
207
 
186
208
  if (!rb_block_given_p()) {
187
- return rb_enumeratorize(self, rb_str_new2("search"), 1, &query);
209
+ return rb_enumeratorize(self, rb_str_new2("search"), argc, argv);
188
210
  }
189
211
 
190
212
  void *graph;
191
213
  TypedData_Get_Struct(self, void *, &graph_type, graph);
192
214
 
193
- return rdxr_graph_yield_search_results(self, rdx_graph_declarations_search(graph, StringValueCStr(query)));
215
+ size_t length = (size_t)argc;
216
+ char **converted = rdxi_str_array_to_char(queries, length);
217
+ void *iter = rdx_graph_declarations_search(graph, (const char *const *)converted, length);
218
+ rdxi_free_str_array(converted, length);
219
+
220
+ return rdxr_graph_yield_search_results(self, iter);
194
221
  }
195
222
 
196
- // Graph#fuzzy_search: (String query) -> Enumerator[Declaration]
197
- // Returns an enumerator that yields declarations matching the query fuzzily
198
- static VALUE rdxr_graph_fuzzy_search(VALUE self, VALUE query) {
199
- Check_Type(query, T_STRING);
223
+ /*
224
+ * call-seq:
225
+ * fuzzy_search(*queries) -> Enumerator[Rubydex::Declaration]
226
+ *
227
+ * Returns an enumerator that yields declarations whose name matches any of the queries fuzzily.
228
+ */
229
+ static VALUE rdxr_graph_fuzzy_search(int argc, VALUE *argv, VALUE self) {
230
+ rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
231
+ VALUE queries = rb_ary_new_from_values(argc, argv);
232
+ rdxi_check_array_of_strings(queries);
200
233
 
201
234
  if (!rb_block_given_p()) {
202
- return rb_enumeratorize(self, rb_str_new2("fuzzy_search"), 1, &query);
235
+ return rb_enumeratorize(self, rb_str_new2("fuzzy_search"), argc, argv);
203
236
  }
204
237
 
205
238
  void *graph;
206
239
  TypedData_Get_Struct(self, void *, &graph_type, graph);
207
240
 
208
- return rdxr_graph_yield_search_results(self, rdx_graph_declarations_fuzzy_search(graph, StringValueCStr(query)));
241
+ size_t length = (size_t)argc;
242
+ char **converted = rdxi_str_array_to_char(queries, length);
243
+ void *iter = rdx_graph_declarations_fuzzy_search(graph, (const char *const *)converted, length);
244
+ rdxi_free_str_array(converted, length);
245
+
246
+ return rdxr_graph_yield_search_results(self, iter);
209
247
  }
210
248
 
211
249
  // Body function for rb_ensure in Graph#documents
@@ -243,8 +281,12 @@ static VALUE graph_documents_size(VALUE self, VALUE _args, VALUE _eobj) {
243
281
  return SIZET2NUM(len);
244
282
  }
245
283
 
246
- // Graph#documents: () -> Enumerator[Document]
247
- // Returns an enumerator that yields all documents lazily
284
+ /*
285
+ * call-seq:
286
+ * documents -> Enumerator[Rubydex::Document]
287
+ *
288
+ * Returns an enumerator that yields all documents lazily.
289
+ */
248
290
  static VALUE rdxr_graph_documents(VALUE self) {
249
291
  if (!rb_block_given_p()) {
250
292
  return rb_enumeratorize_with_size(self, rb_str_new2("documents"), 0, NULL, graph_documents_size);
@@ -260,8 +302,12 @@ static VALUE rdxr_graph_documents(VALUE self) {
260
302
  return self;
261
303
  }
262
304
 
263
- // Graph#[]: (String fully_qualified_name) -> Declaration
264
- // Returns a declaration handle for the given ID
305
+ /*
306
+ * call-seq:
307
+ * graph[fully_qualified_name] -> Rubydex::Declaration?
308
+ *
309
+ * Returns the declaration for the fully qualified name, or nil when no declaration exists.
310
+ */
265
311
  static VALUE rdxr_graph_aref(VALUE self, VALUE key) {
266
312
  void *graph;
267
313
  TypedData_Get_Struct(self, void *, &graph_type, graph);
@@ -294,8 +340,12 @@ static VALUE graph_constant_references_size(VALUE self, VALUE _args, VALUE _eobj
294
340
  return SIZET2NUM(len);
295
341
  }
296
342
 
297
- // Graph#constant_references: () -> Enumerator[ConstantReference]
298
- // Returns an enumerator that yields constant references lazily
343
+ /*
344
+ * call-seq:
345
+ * constant_references -> Enumerator[Rubydex::ConstantReference]
346
+ *
347
+ * Returns an enumerator that yields constant references lazily.
348
+ */
299
349
  static VALUE rdxr_graph_constant_references(VALUE self) {
300
350
  if (!rb_block_given_p()) {
301
351
  return rb_enumeratorize_with_size(self, rb_str_new2("constant_references"), 0, NULL,
@@ -324,8 +374,12 @@ static VALUE graph_method_references_size(VALUE self, VALUE _args, VALUE _eobj)
324
374
  return SIZET2NUM(len);
325
375
  }
326
376
 
327
- // Graph#method_references: () -> Enumerator[MethodReference]
328
- // Returns an enumerator that yields method references lazily
377
+ /*
378
+ * call-seq:
379
+ * method_references -> Enumerator[Rubydex::MethodReference]
380
+ *
381
+ * Returns an enumerator that yields method references lazily.
382
+ */
329
383
  static VALUE rdxr_graph_method_references(VALUE self) {
330
384
  if (!rb_block_given_p()) {
331
385
  return rb_enumeratorize_with_size(self, rb_str_new2("method_references"), 0, NULL,
@@ -342,8 +396,12 @@ static VALUE rdxr_graph_method_references(VALUE self) {
342
396
  return self;
343
397
  }
344
398
 
345
- // Graph#document: (String uri) -> Document?
346
- // Returns the Document for the given URI, or nil if it doesn't exist.
399
+ /*
400
+ * call-seq:
401
+ * document(uri) -> Rubydex::Document?
402
+ *
403
+ * Returns the document for the URI, or nil if it does not exist.
404
+ */
347
405
  static VALUE rdxr_graph_document(VALUE self, VALUE uri) {
348
406
  Check_Type(uri, T_STRING);
349
407
 
@@ -360,9 +418,13 @@ static VALUE rdxr_graph_document(VALUE self, VALUE uri) {
360
418
  return rb_class_new_instance(2, argv, cDocument);
361
419
  }
362
420
 
363
- // Graph#delete_document: (String uri) -> Document?
364
- // Deletes a document and all of its definitions from the graph.
365
- // Returns the removed Document or nil if it doesn't exist.
421
+ /*
422
+ * call-seq:
423
+ * delete_document(uri) -> Rubydex::Document?
424
+ *
425
+ * Deletes a document and all of its definitions from the graph. Returns the removed document, or nil if it does not
426
+ * exist.
427
+ */
366
428
  static VALUE rdxr_graph_delete_document(VALUE self, VALUE uri) {
367
429
  Check_Type(uri, T_STRING);
368
430
 
@@ -379,8 +441,12 @@ static VALUE rdxr_graph_delete_document(VALUE self, VALUE uri) {
379
441
  return rb_class_new_instance(2, argv, cDocument);
380
442
  }
381
443
 
382
- // Graph#resolve: () -> self
383
- // Runs the resolver to compute declarations and ownership
444
+ /*
445
+ * call-seq:
446
+ * resolve -> self
447
+ *
448
+ * Runs the resolver to compute declarations and ownership.
449
+ */
384
450
  static VALUE rdxr_graph_resolve(VALUE self) {
385
451
  void *graph;
386
452
  TypedData_Get_Struct(self, void *, &graph_type, graph);
@@ -388,8 +454,12 @@ static VALUE rdxr_graph_resolve(VALUE self) {
388
454
  return self;
389
455
  }
390
456
 
391
- // Graph#encoding=: (String) -> void
392
- // Sets the encoding used for transforming byte offsets into LSP code unit line/column positions
457
+ /*
458
+ * call-seq:
459
+ * encoding=(encoding) -> nil
460
+ *
461
+ * Sets the encoding used for transforming byte offsets into LSP code unit line and column positions.
462
+ */
393
463
  static VALUE rdxr_graph_set_encoding(VALUE self, VALUE encoding) {
394
464
  Check_Type(encoding, T_STRING);
395
465
 
@@ -404,8 +474,12 @@ static VALUE rdxr_graph_set_encoding(VALUE self, VALUE encoding) {
404
474
  return Qnil;
405
475
  }
406
476
 
407
- // Graph#resolve_constant: (String, Array[String]) -> Declaration?
408
- // Runs the resolver on a single constant reference to determine what it points to
477
+ /*
478
+ * call-seq:
479
+ * resolve_constant(name, nesting) -> Rubydex::Declaration?
480
+ *
481
+ * Runs the resolver on a single constant reference to determine what it points to.
482
+ */
409
483
  static VALUE rdxr_graph_resolve_constant(VALUE self, VALUE const_name, VALUE nesting) {
410
484
  Check_Type(const_name, T_STRING);
411
485
  rdxi_check_array_of_strings(nesting);
@@ -433,8 +507,12 @@ static VALUE rdxr_graph_resolve_constant(VALUE self, VALUE const_name, VALUE nes
433
507
  return rb_class_new_instance(2, argv, decl_class);
434
508
  }
435
509
 
436
- // Graph#resolve_require_path: (String require_path, Array[String] load_paths) -> Document?
437
- // Resolves a require path to its Document.
510
+ /*
511
+ * call-seq:
512
+ * resolve_require_path(require_path, load_paths) -> Rubydex::Document?
513
+ *
514
+ * Resolves a require path to its document.
515
+ */
438
516
  static VALUE rdxr_graph_resolve_require_path(VALUE self, VALUE require_path, VALUE load_paths) {
439
517
  Check_Type(require_path, T_STRING);
440
518
  rdxi_check_array_of_strings(load_paths);
@@ -459,8 +537,12 @@ static VALUE rdxr_graph_resolve_require_path(VALUE self, VALUE require_path, VAL
459
537
  return rb_class_new_instance(2, argv, cDocument);
460
538
  }
461
539
 
462
- // Graph#require_paths: (Array[String] load_path) -> Array[String]
463
- // Returns all require paths for completion.
540
+ /*
541
+ * call-seq:
542
+ * require_paths(load_paths) -> Array[String]
543
+ *
544
+ * Returns all require paths for completion.
545
+ */
464
546
  static VALUE rdxr_graph_require_paths(VALUE self, VALUE load_path) {
465
547
  rdxi_check_array_of_strings(load_path);
466
548
 
@@ -488,8 +570,12 @@ static VALUE rdxr_graph_require_paths(VALUE self, VALUE load_path) {
488
570
  return array;
489
571
  }
490
572
 
491
- // Graph#check_integrity: () -> Array[Rubydex::IntegrityFailure]
492
- // Returns an array of IntegrityFailure objects, empty if no issues found
573
+ /*
574
+ * call-seq:
575
+ * check_integrity -> Array[Rubydex::IntegrityFailure]
576
+ *
577
+ * Returns an array of integrity failures, or an empty array if no issues were found.
578
+ */
493
579
  static VALUE rdxr_graph_check_integrity(VALUE self) {
494
580
  void *graph;
495
581
  TypedData_Get_Struct(self, void *, &graph_type, graph);
@@ -514,7 +600,12 @@ static VALUE rdxr_graph_check_integrity(VALUE self) {
514
600
  return array;
515
601
  }
516
602
 
517
- // Graph#diagnostics -> Array[Rubydex::Diagnostic]
603
+ /*
604
+ * call-seq:
605
+ * diagnostics -> Array[Rubydex::Diagnostic]
606
+ *
607
+ * Returns diagnostics emitted while indexing or resolving the graph.
608
+ */
518
609
  static VALUE rdxr_graph_diagnostics(VALUE self) {
519
610
  void *graph;
520
611
  TypedData_Get_Struct(self, void *, &graph_type, graph);
@@ -531,7 +622,7 @@ static VALUE rdxr_graph_diagnostics(VALUE self) {
531
622
  for (size_t i = 0; i < array->len; i++) {
532
623
  DiagnosticEntry entry = array->items[i];
533
624
  VALUE message = entry.message == NULL ? Qnil : rb_utf8_str_new_cstr(entry.message);
534
- VALUE rule = rb_str_new2(entry.rule);
625
+ VALUE rule = rb_str_intern(rb_str_new2(entry.rule));
535
626
  VALUE location = rdxi_build_location_value(entry.location);
536
627
 
537
628
  VALUE kwargs = rb_hash_new();
@@ -603,10 +694,13 @@ static VALUE completion_result_to_ruby_array(struct CompletionResult result, VAL
603
694
  return ruby_array;
604
695
  }
605
696
 
606
- // Graph#complete_expression: (Array[String] nesting, self_receiver:) -> Array[Declaration | Keyword]
607
- // Returns completion candidates for an expression context.
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.
697
+ /*
698
+ * call-seq:
699
+ * complete_expression(nesting, self_receiver:) -> Array[Rubydex::Declaration | Rubydex::Keyword]
700
+ *
701
+ * Returns completion candidates for an expression context. The nesting array represents the lexical scope stack. The
702
+ * required self_receiver keyword argument overrides the self type; pass nil when the self type is unknown.
703
+ */
610
704
  static VALUE rdxr_graph_complete_expression(int argc, VALUE *argv, VALUE self) {
611
705
  VALUE nesting, opts;
612
706
  rb_scan_args(argc, argv, "1:", &nesting, &opts);
@@ -627,11 +721,13 @@ static VALUE rdxr_graph_complete_expression(int argc, VALUE *argv, VALUE self) {
627
721
  return completion_result_to_ruby_array(result, self);
628
722
  }
629
723
 
630
- // Graph#complete_namespace_access: (String name, self_receiver:) -> Array[Declaration]
631
- // Returns completion candidates after a namespace access operator (e.g., `Foo::`).
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.
724
+ /*
725
+ * call-seq:
726
+ * complete_namespace_access(name, self_receiver:) -> Array[Rubydex::Declaration]
727
+ *
728
+ * Returns completion candidates after a namespace access operator such as Foo::. The required self_receiver keyword
729
+ * argument is the caller's runtime self type; pass nil when there is no caller context.
730
+ */
635
731
  static VALUE rdxr_graph_complete_namespace_access(int argc, VALUE *argv, VALUE self) {
636
732
  VALUE name, opts;
637
733
  rb_scan_args(argc, argv, "1:", &name, &opts);
@@ -647,10 +743,13 @@ static VALUE rdxr_graph_complete_namespace_access(int argc, VALUE *argv, VALUE s
647
743
  return completion_result_to_ruby_array(result, self);
648
744
  }
649
745
 
650
- // Graph#complete_method_call: (String name, self_receiver:) -> Array[Declaration]
651
- // Returns completion candidates after a method call operator (e.g., `foo.`).
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.
746
+ /*
747
+ * call-seq:
748
+ * complete_method_call(name, self_receiver:) -> Array[Rubydex::Method]
749
+ *
750
+ * Returns completion candidates after a method call operator such as foo. The required self_receiver keyword argument
751
+ * is the caller's runtime self type; pass nil when there is no caller context.
752
+ */
654
753
  static VALUE rdxr_graph_complete_method_call(int argc, VALUE *argv, VALUE self) {
655
754
  VALUE name, opts;
656
755
  rb_scan_args(argc, argv, "1:", &name, &opts);
@@ -666,9 +765,13 @@ static VALUE rdxr_graph_complete_method_call(int argc, VALUE *argv, VALUE self)
666
765
  return completion_result_to_ruby_array(result, self);
667
766
  }
668
767
 
669
- // Graph#complete_method_argument: (String name, Array[String] nesting, self_receiver:) -> Array[Declaration | Keyword | KeywordParameter]
670
- // Returns completion candidates inside a method call's argument list (e.g., `foo.bar(|)`).
671
- // See complete_expression for semantics of self_receiver (required, may be nil).
768
+ /*
769
+ * call-seq:
770
+ * complete_method_argument(name, nesting, self_receiver:) -> Array[Rubydex::Declaration | Rubydex::Keyword | Rubydex::KeywordParameter]
771
+ *
772
+ * Returns completion candidates inside a method call's argument list. See complete_expression for self_receiver
773
+ * semantics.
774
+ */
672
775
  static VALUE rdxr_graph_complete_method_argument(int argc, VALUE *argv, VALUE self) {
673
776
  VALUE name, nesting, opts;
674
777
  rb_scan_args(argc, argv, "2:", &name, &nesting, &opts);
@@ -691,8 +794,12 @@ static VALUE rdxr_graph_complete_method_argument(int argc, VALUE *argv, VALUE se
691
794
  return completion_result_to_ruby_array(result, self);
692
795
  }
693
796
 
694
- // Graph#exclude_paths: (Array[String] paths) -> void
695
- // Excludes the given paths from file discovery during indexing.
797
+ /*
798
+ * call-seq:
799
+ * exclude_paths(paths) -> nil
800
+ *
801
+ * Excludes the paths from file discovery during indexing.
802
+ */
696
803
  static VALUE rdxr_graph_exclude_paths(VALUE self, VALUE paths) {
697
804
  Check_Type(paths, T_ARRAY);
698
805
  rdxi_check_array_of_strings(paths);
@@ -709,8 +816,12 @@ static VALUE rdxr_graph_exclude_paths(VALUE self, VALUE paths) {
709
816
  return Qnil;
710
817
  }
711
818
 
712
- // Graph#excluded_paths: () -> Array[String]
713
- // Returns the list of paths currently excluded from file discovery.
819
+ /*
820
+ * call-seq:
821
+ * excluded_paths -> Array[String]
822
+ *
823
+ * Returns the paths currently excluded from file discovery.
824
+ */
714
825
  static VALUE rdxr_graph_excluded_paths(VALUE self) {
715
826
  void *graph;
716
827
  TypedData_Get_Struct(self, void*, &graph_type, graph);
@@ -731,8 +842,81 @@ static VALUE rdxr_graph_excluded_paths(VALUE self) {
731
842
  return array;
732
843
  }
733
844
 
734
- // Graph#keyword: (String name) -> Keyword?
735
- // Returns a Keyword object for the given keyword name, or nil if it is not a keyword.
845
+ /*
846
+ * call-seq:
847
+ * workspace_path -> String
848
+ *
849
+ * Returns the root directory of the workspace being indexed.
850
+ */
851
+ static VALUE rdxr_graph_workspace_path(VALUE self) {
852
+ void *graph;
853
+ TypedData_Get_Struct(self, void*, &graph_type, graph);
854
+
855
+ const char *result = rdx_graph_workspace_path(graph);
856
+ if (result == NULL) {
857
+ rb_raise(rb_eRuntimeError, "Converting workspace path to Ruby string failed");
858
+ }
859
+
860
+ VALUE path = rdxi_owned_c_string_to_ruby(result);
861
+ return path;
862
+ }
863
+
864
+ /*
865
+ * call-seq:
866
+ * workspace_path=(path) -> void
867
+ *
868
+ * Sets the root directory of the workspace being indexed.
869
+ */
870
+ static VALUE rdxr_graph_set_workspace_path(VALUE self, VALUE path) {
871
+ Check_Type(path, T_STRING);
872
+
873
+ void *graph;
874
+ TypedData_Get_Struct(self, void*, &graph_type, graph);
875
+
876
+ rdx_graph_set_workspace_path(graph, StringValueCStr(path));
877
+ return path;
878
+ }
879
+
880
+ /*
881
+ * call-seq:
882
+ * load_config(config_path = nil) -> void
883
+ *
884
+ * Loads a configuration file for the graph. If `config_path` is nil, loads the default configuration file at
885
+ * `workspace_path/rubydex.toml` if it exists. Will raise on malformed files or if an explicit path is given but the
886
+ * file does not exist.
887
+ */
888
+ static VALUE rdxr_graph_load_config(int argc, VALUE *argv, VALUE self) {
889
+ VALUE config_path;
890
+ rb_scan_args(argc, argv, "01", &config_path);
891
+
892
+ void *graph;
893
+ TypedData_Get_Struct(self, void *, &graph_type, graph);
894
+
895
+ const char *config_path_cstr = NULL;
896
+
897
+ if (!NIL_P(config_path)) {
898
+ Check_Type(config_path, T_STRING);
899
+ config_path_cstr = StringValueCStr(config_path);
900
+ }
901
+
902
+ const char *error = rdx_graph_load_config(graph, config_path_cstr);
903
+ if (error == NULL) {
904
+ return Qnil;
905
+ }
906
+
907
+ VALUE message = rb_utf8_str_new_cstr(error);
908
+ free_c_string(error);
909
+
910
+ VALUE config_error = rb_const_get(mRubydex, rb_intern("ConfigError"));
911
+ rb_exc_raise(rb_exc_new_str(config_error, message));
912
+ }
913
+
914
+ /*
915
+ * call-seq:
916
+ * keyword(name) -> Rubydex::Keyword?
917
+ *
918
+ * Returns the keyword object for the name, or nil if it is not a Ruby keyword.
919
+ */
736
920
  static VALUE rdxr_graph_keyword(VALUE self, VALUE name) {
737
921
  Check_Type(name, T_STRING);
738
922
 
@@ -772,8 +956,8 @@ void rdxi_initialize_graph(VALUE moduleRubydex) {
772
956
  rb_define_method(cGraph, "diagnostics", rdxr_graph_diagnostics, 0);
773
957
  rb_define_method(cGraph, "check_integrity", rdxr_graph_check_integrity, 0);
774
958
  rb_define_method(cGraph, "[]", rdxr_graph_aref, 1);
775
- rb_define_method(cGraph, "search", rdxr_graph_search, 1);
776
- rb_define_method(cGraph, "fuzzy_search", rdxr_graph_fuzzy_search, 1);
959
+ rb_define_method(cGraph, "search", rdxr_graph_search, -1);
960
+ rb_define_method(cGraph, "fuzzy_search", rdxr_graph_fuzzy_search, -1);
777
961
  rb_define_method(cGraph, "encoding=", rdxr_graph_set_encoding, 1);
778
962
  rb_define_method(cGraph, "resolve_require_path", rdxr_graph_resolve_require_path, 2);
779
963
  rb_define_method(cGraph, "require_paths", rdxr_graph_require_paths, 1);
@@ -783,5 +967,8 @@ void rdxi_initialize_graph(VALUE moduleRubydex) {
783
967
  rb_define_method(cGraph, "complete_method_argument", rdxr_graph_complete_method_argument, -1);
784
968
  rb_define_method(cGraph, "exclude_paths", rdxr_graph_exclude_paths, 1);
785
969
  rb_define_method(cGraph, "excluded_paths", rdxr_graph_excluded_paths, 0);
970
+ rb_define_method(cGraph, "workspace_path", rdxr_graph_workspace_path, 0);
971
+ rb_define_method(cGraph, "workspace_path=", rdxr_graph_set_workspace_path, 1);
972
+ rb_define_method(cGraph, "load_config", rdxr_graph_load_config, -1);
786
973
  rb_define_method(cGraph, "keyword", rdxr_graph_keyword, 1);
787
974
  }
data/ext/rubydex/handle.h CHANGED
@@ -1,6 +1,7 @@
1
1
  #ifndef RUBYDEX_HANDLE_H
2
2
  #define RUBYDEX_HANDLE_H
3
3
 
4
+ #include "graph.h"
4
5
  #include "ruby.h"
5
6
 
6
7
  typedef struct {
@@ -34,6 +35,18 @@ static const rb_data_type_t handle_type = {
34
35
  .flags = RUBY_TYPED_FREE_IMMEDIATELY,
35
36
  };
36
37
 
38
+ static inline void *rdxi_graph_from_handle(VALUE self, HandleData **out_data) {
39
+ HandleData *data;
40
+ TypedData_Get_Struct(self, HandleData, &handle_type, data);
41
+
42
+ void *graph;
43
+ TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
44
+
45
+ *out_data = data;
46
+
47
+ return graph;
48
+ }
49
+
37
50
  static VALUE rdxr_handle_alloc(VALUE klass) {
38
51
  HandleData *data = ALLOC(HandleData);
39
52
 
@@ -1,5 +1,10 @@
1
1
  #include "location.h"
2
2
 
3
+ /*
4
+ * RDoc parser workaround for https://github.com/ruby/rdoc/issues/1744:
5
+ * mRubydex = rb_define_module("Rubydex")
6
+ */
7
+
3
8
  VALUE cLocation;
4
9
 
5
10
  VALUE rdxi_build_location_value(Location *loc) {