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
@@ -0,0 +1,94 @@
1
+ use rubydex::diagnostic::{Rule, Severity};
2
+ use std::collections::HashSet;
3
+ use std::path::Path;
4
+ use std::{env, fs};
5
+
6
+ // Takes the built-in diagnostic rules and generates Ruby classes for them in `lib/rubydex/rules`.
7
+ fn main() {
8
+ let root = Path::new(env!("CARGO_MANIFEST_DIR")).join("..").join("..");
9
+ let directory = root.join("lib").join("rubydex").join("rules");
10
+ let mut generated_files = HashSet::new();
11
+
12
+ for rule in Rule::all().iter().copied() {
13
+ write_rule(&directory, rule, &mut generated_files);
14
+ }
15
+
16
+ // Remove stale rules
17
+ for entry in fs::read_dir(&directory).unwrap() {
18
+ let entry = entry.unwrap();
19
+ let path = entry.path();
20
+
21
+ if path.is_file() {
22
+ let file_name = path.file_name().unwrap().to_string_lossy();
23
+
24
+ if !generated_files.contains(&file_name.to_string()) {
25
+ fs::remove_file(path).unwrap();
26
+ }
27
+ }
28
+ }
29
+ }
30
+
31
+ fn write_rule(dir: &Path, rule: Rule, generated_files: &mut HashSet<String>) {
32
+ let documentation = rule
33
+ .documentation()
34
+ .iter()
35
+ .map(|line| format!(" #{line}").trim_end().to_owned())
36
+ .collect::<Vec<String>>()
37
+ .join("\n");
38
+
39
+ let contents = format!(
40
+ "# typed: strict
41
+ # frozen_string_literal: true
42
+
43
+ # This file is generated by `generate_ruby_rules.rs`. Do not edit this manually.
44
+
45
+ module Rubydex
46
+ module Rules
47
+ {documentation}
48
+ class {name} < Rule
49
+ class << self
50
+ # @override
51
+ #: -> singleton(Severity::Base)
52
+ def default_severity
53
+ {severity}
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ ",
60
+ name = rule.name(),
61
+ severity = to_ruby_severity(rule.default_severity()),
62
+ );
63
+
64
+ let file_name = format!("{}.rb", snake_case(rule.name()));
65
+ fs::write(dir.join(&file_name), contents).unwrap();
66
+ generated_files.insert(file_name);
67
+ }
68
+
69
+ fn to_ruby_severity(severity: Severity) -> &'static str {
70
+ match severity {
71
+ Severity::Error => "Severity::Error",
72
+ Severity::Warning => "Severity::Warning",
73
+ Severity::Information => "Severity::Information",
74
+ Severity::Hint => "Severity::Hint",
75
+ }
76
+ }
77
+
78
+ fn snake_case(name: &str) -> String {
79
+ let mut result = String::with_capacity(name.len() + 4);
80
+
81
+ for (index, character) in name.char_indices() {
82
+ if character.is_uppercase() {
83
+ if index != 0 {
84
+ result.push('_');
85
+ }
86
+
87
+ result.extend(character.to_lowercase());
88
+ } else {
89
+ result.push(character);
90
+ }
91
+ }
92
+
93
+ result
94
+ }