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.
- checksums.yaml +4 -4
- data/README.md +29 -7
- data/THIRD_PARTY_LICENSES.html +238 -2
- data/exe/rdx +2 -149
- data/ext/rubydex/config.c +140 -0
- data/ext/rubydex/config.h +16 -0
- data/ext/rubydex/definition.c +34 -0
- data/ext/rubydex/definition.h +3 -0
- data/ext/rubydex/diagnostic.c +28 -1
- data/ext/rubydex/diagnostic.h +2 -0
- data/ext/rubydex/extconf.rb +4 -2
- data/ext/rubydex/graph.c +71 -55
- data/ext/rubydex/graph.h +6 -0
- data/ext/rubydex/query.c +398 -16
- data/ext/rubydex/rubydex.c +2 -0
- data/ext/rubydex/utils.c +11 -4
- data/lib/ruby_lsp/rubydex/addon.rb +211 -0
- data/lib/rubydex/cli/command/console.rb +55 -0
- data/lib/rubydex/cli/command/lint/explain.rb +76 -0
- data/lib/rubydex/cli/command/lint.rb +208 -0
- data/lib/rubydex/cli/command/mcp.rb +30 -0
- data/lib/rubydex/cli/command/query.rb +70 -0
- data/lib/rubydex/cli/command/skill.rb +69 -0
- data/lib/rubydex/cli/command.rb +168 -0
- data/lib/rubydex/cli.rb +93 -0
- data/lib/rubydex/config.rb +59 -0
- data/lib/rubydex/diagnostic.rb +12 -3
- data/lib/rubydex/errors.rb +42 -1
- data/lib/rubydex/graph.rb +10 -3
- data/lib/rubydex/linter/custom_rule.rb +97 -0
- data/lib/rubydex/linter/helpers/path_helpers.rb +78 -0
- data/lib/rubydex/linter/helpers/source_access_helpers.rb +31 -0
- data/lib/rubydex/linter/rule_loader.rb +36 -0
- data/lib/rubydex/linter/rule_test_case.rb +343 -0
- data/lib/rubydex/linter/runner.rb +56 -0
- data/lib/rubydex/linter.rb +19 -0
- data/lib/rubydex/location.rb +3 -0
- data/lib/rubydex/mcp_server.rb +1 -2
- data/lib/rubydex/related_information.rb +17 -0
- data/lib/rubydex/rule.rb +33 -0
- data/lib/rubydex/rules/dynamic_ancestor.rb +29 -0
- data/lib/rubydex/rules/dynamic_constant_reference.rb +25 -0
- data/lib/rubydex/rules/dynamic_singleton_definition.rb +30 -0
- data/lib/rubydex/rules/invalid_constant_visibility.rb +28 -0
- data/lib/rubydex/rules/invalid_method_visibility.rb +28 -0
- data/lib/rubydex/rules/parse_error.rb +25 -0
- data/lib/rubydex/rules/parse_warning.rb +28 -0
- data/lib/rubydex/rules/top_level_mixin_self.rb +27 -0
- data/lib/rubydex/rules/undefined_constant_visibility_target.rb +27 -0
- data/lib/rubydex/rules/undefined_method_visibility_target.rb +27 -0
- data/lib/rubydex/severity.rb +70 -0
- data/lib/rubydex/skill.rb +89 -0
- data/lib/rubydex/skill_registry.rb +62 -0
- data/lib/rubydex/version.rb +1 -1
- data/lib/rubydex.rb +8 -0
- data/lib/rubydex_linter/rules/rule_structure.rb +140 -0
- data/rbi/rubydex.rbi +464 -21
- data/rust/Cargo.lock +2 -2
- data/rust/rubydex/Cargo.toml +5 -1
- data/rust/rubydex/benches/graph_memory.rs +3 -5
- data/rust/rubydex/src/bin/generate_ruby_rules.rs +94 -0
- data/rust/rubydex/src/config.rs +538 -157
- data/rust/rubydex/src/diagnostic.rs +162 -45
- data/rust/rubydex/src/errors.rs +0 -1
- data/rust/rubydex/src/indexing/local_graph.rs +6 -5
- data/rust/rubydex/src/indexing/rbs_indexer.rs +270 -6
- data/rust/rubydex/src/indexing/ruby_indexer.rs +10 -12
- data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +134 -81
- data/rust/rubydex/src/lib.rs +1 -0
- data/rust/rubydex/src/listing.rs +26 -1
- data/rust/rubydex/src/main.rs +7 -4
- data/rust/rubydex/src/model/declaration.rs +302 -219
- data/rust/rubydex/src/model/graph.rs +27 -40
- data/rust/rubydex/src/model/name.rs +58 -17
- data/rust/rubydex/src/operation/ruby_builder.rs +30 -45
- data/rust/rubydex/src/path_helpers.rs +77 -0
- data/rust/rubydex/src/query/cypher/schema.rs +63 -0
- data/rust/rubydex/src/query/cypher/tests.rs +26 -1
- data/rust/rubydex/src/query/cypher.rs +8 -11
- data/rust/rubydex/src/query.rs +314 -44
- data/rust/rubydex/src/resolution.rs +139 -187
- data/rust/rubydex/src/resolution_tests.rs +247 -19
- data/rust/rubydex/src/test_utils/context.rs +2 -1
- data/rust/rubydex/src/test_utils/graph_test.rs +26 -12
- data/rust/rubydex/src/test_utils/local_graph_test.rs +19 -0
- data/rust/rubydex/tests/cli.rs +4 -4
- data/rust/rubydex-sys/src/config_api.rs +205 -0
- data/rust/rubydex-sys/src/cypher_api.rs +791 -0
- data/rust/rubydex-sys/src/definition_api.rs +68 -1
- data/rust/rubydex-sys/src/diagnostic_api.rs +42 -8
- data/rust/rubydex-sys/src/graph_api.rs +125 -205
- data/rust/rubydex-sys/src/lib.rs +2 -0
- data/rust/rubydex-sys/src/name_api.rs +49 -17
- data/rust/rubydex-sys/src/utils.rs +37 -0
- data/skills/send-private-method/SKILL.md +133 -0
- metadata +42 -2
data/ext/rubydex/definition.c
CHANGED
|
@@ -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);
|
data/ext/rubydex/definition.h
CHANGED
|
@@ -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
|
|
data/ext/rubydex/diagnostic.c
CHANGED
|
@@ -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
|
-
|
|
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
|
+
}
|
data/ext/rubydex/diagnostic.h
CHANGED
|
@@ -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
|
data/ext/rubydex/extconf.rb
CHANGED
|
@@ -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(
|
|
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 << "
|
|
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,
|
|
514
|
+
* resolve_constant(name, context) -> Rubydex::Declaration?
|
|
489
515
|
*
|
|
490
|
-
* Runs the resolver on a single constant reference
|
|
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
|
|
519
|
+
static VALUE rdxr_graph_resolve_constant(VALUE self, VALUE const_name, VALUE context) {
|
|
493
520
|
Check_Type(const_name, T_STRING);
|
|
494
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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,
|
|
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
|
-
*
|
|
925
|
+
* load_config(config) -> void
|
|
876
926
|
*
|
|
877
|
-
*
|
|
927
|
+
* Applies a parsed Rubydex::Config to the graph.
|
|
878
928
|
*/
|
|
879
|
-
static VALUE
|
|
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
|
-
|
|
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
|
-
|
|
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, "
|
|
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
|