rubydex 0.1.0.beta11 → 0.1.0.beta13

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 (108) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +23 -23
  3. data/README.md +125 -125
  4. data/THIRD_PARTY_LICENSES.html +2018 -945
  5. data/exe/rdx +47 -47
  6. data/ext/rubydex/declaration.c +453 -388
  7. data/ext/rubydex/declaration.h +23 -23
  8. data/ext/rubydex/definition.c +284 -197
  9. data/ext/rubydex/definition.h +28 -28
  10. data/ext/rubydex/diagnostic.c +6 -6
  11. data/ext/rubydex/diagnostic.h +11 -11
  12. data/ext/rubydex/document.c +97 -98
  13. data/ext/rubydex/document.h +10 -10
  14. data/ext/rubydex/extconf.rb +146 -127
  15. data/ext/rubydex/graph.c +701 -512
  16. data/ext/rubydex/graph.h +10 -10
  17. data/ext/rubydex/handle.h +44 -44
  18. data/ext/rubydex/location.c +22 -22
  19. data/ext/rubydex/location.h +15 -15
  20. data/ext/rubydex/reference.c +123 -104
  21. data/ext/rubydex/reference.h +15 -16
  22. data/ext/rubydex/rubydex.c +22 -22
  23. data/ext/rubydex/utils.c +108 -86
  24. data/ext/rubydex/utils.h +34 -28
  25. data/lib/rubydex/comment.rb +17 -17
  26. data/lib/rubydex/declaration.rb +11 -0
  27. data/lib/rubydex/diagnostic.rb +21 -21
  28. data/lib/rubydex/failures.rb +15 -15
  29. data/lib/rubydex/graph.rb +98 -92
  30. data/lib/rubydex/keyword.rb +17 -0
  31. data/lib/rubydex/keyword_parameter.rb +13 -0
  32. data/lib/rubydex/location.rb +90 -90
  33. data/lib/rubydex/mixin.rb +22 -0
  34. data/lib/rubydex/version.rb +5 -5
  35. data/lib/rubydex.rb +24 -20
  36. data/rbi/rubydex.rbi +425 -310
  37. data/rust/Cargo.lock +1851 -1851
  38. data/rust/Cargo.toml +29 -29
  39. data/rust/about.toml +10 -10
  40. data/rust/{about.hbs → about_templates/about.hbs} +81 -78
  41. data/rust/about_templates/mingw_licenses.hbs +1071 -0
  42. data/rust/rubydex/Cargo.toml +42 -42
  43. data/rust/rubydex/src/compile_assertions.rs +13 -13
  44. data/rust/rubydex/src/diagnostic.rs +110 -109
  45. data/rust/rubydex/src/errors.rs +28 -28
  46. data/rust/rubydex/src/indexing/local_graph.rs +224 -224
  47. data/rust/rubydex/src/indexing/rbs_indexer.rs +1551 -1554
  48. data/rust/rubydex/src/indexing/ruby_indexer.rs +2329 -6753
  49. data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +4962 -0
  50. data/rust/rubydex/src/indexing.rs +210 -210
  51. data/rust/rubydex/src/integrity.rs +279 -278
  52. data/rust/rubydex/src/job_queue.rs +199 -205
  53. data/rust/rubydex/src/lib.rs +17 -17
  54. data/rust/rubydex/src/listing.rs +371 -272
  55. data/rust/rubydex/src/main.rs +160 -160
  56. data/rust/rubydex/src/model/built_in.rs +83 -0
  57. data/rust/rubydex/src/model/comment.rs +24 -24
  58. data/rust/rubydex/src/model/declaration.rs +679 -588
  59. data/rust/rubydex/src/model/definitions.rs +1682 -1602
  60. data/rust/rubydex/src/model/document.rs +222 -252
  61. data/rust/rubydex/src/model/encoding.rs +22 -22
  62. data/rust/rubydex/src/model/graph.rs +3782 -3556
  63. data/rust/rubydex/src/model/id.rs +110 -110
  64. data/rust/rubydex/src/model/identity_maps.rs +58 -58
  65. data/rust/rubydex/src/model/ids.rs +60 -38
  66. data/rust/rubydex/src/model/keywords.rs +256 -256
  67. data/rust/rubydex/src/model/name.rs +298 -298
  68. data/rust/rubydex/src/model/references.rs +111 -111
  69. data/rust/rubydex/src/model/string_ref.rs +50 -50
  70. data/rust/rubydex/src/model/visibility.rs +41 -41
  71. data/rust/rubydex/src/model.rs +15 -14
  72. data/rust/rubydex/src/offset.rs +147 -147
  73. data/rust/rubydex/src/position.rs +6 -6
  74. data/rust/rubydex/src/query.rs +1841 -1700
  75. data/rust/rubydex/src/resolution.rs +1852 -5895
  76. data/rust/rubydex/src/resolution_tests.rs +4701 -0
  77. data/rust/rubydex/src/stats/memory.rs +71 -71
  78. data/rust/rubydex/src/stats/orphan_report.rs +264 -263
  79. data/rust/rubydex/src/stats/timer.rs +127 -127
  80. data/rust/rubydex/src/stats.rs +11 -11
  81. data/rust/rubydex/src/test_utils/context.rs +226 -226
  82. data/rust/rubydex/src/test_utils/graph_test.rs +730 -679
  83. data/rust/rubydex/src/test_utils/local_graph_test.rs +602 -602
  84. data/rust/rubydex/src/test_utils.rs +52 -52
  85. data/rust/rubydex/src/visualization/dot.rs +192 -176
  86. data/rust/rubydex/src/visualization.rs +6 -6
  87. data/rust/rubydex/tests/cli.rs +185 -167
  88. data/rust/rubydex-mcp/Cargo.toml +28 -28
  89. data/rust/rubydex-mcp/src/main.rs +48 -48
  90. data/rust/rubydex-mcp/src/server.rs +1145 -1145
  91. data/rust/rubydex-mcp/src/tools.rs +49 -49
  92. data/rust/rubydex-mcp/tests/mcp.rs +302 -302
  93. data/rust/rubydex-sys/Cargo.toml +20 -20
  94. data/rust/rubydex-sys/build.rs +14 -14
  95. data/rust/rubydex-sys/cbindgen.toml +12 -12
  96. data/rust/rubydex-sys/src/declaration_api.rs +485 -469
  97. data/rust/rubydex-sys/src/definition_api.rs +443 -352
  98. data/rust/rubydex-sys/src/diagnostic_api.rs +99 -99
  99. data/rust/rubydex-sys/src/document_api.rs +85 -54
  100. data/rust/rubydex-sys/src/graph_api.rs +1017 -700
  101. data/rust/rubydex-sys/src/lib.rs +79 -9
  102. data/rust/rubydex-sys/src/location_api.rs +79 -79
  103. data/rust/rubydex-sys/src/name_api.rs +187 -135
  104. data/rust/rubydex-sys/src/reference_api.rs +267 -195
  105. data/rust/rubydex-sys/src/utils.rs +70 -70
  106. data/rust/rustfmt.toml +2 -2
  107. metadata +16 -9
  108. data/lib/rubydex/librubydex_sys.so +0 -0
@@ -1,226 +1,226 @@
1
- use super::normalize_indentation;
2
- use std::fs;
3
- use std::path::{Path, PathBuf};
4
- use tempfile::TempDir;
5
-
6
- #[derive(Debug)]
7
- pub struct Context {
8
- _root: TempDir,
9
- absolute_path: PathBuf,
10
- }
11
-
12
- /// Executes a closure with a new temporary context, ensuring cleanup afterwards.
13
- ///
14
- /// # Examples
15
- ///
16
- /// ```
17
- /// use rubydex::test_utils::with_context;
18
- ///
19
- /// with_context(|context| {
20
- /// context.touch("foo.rb");
21
- /// });
22
- /// ```
23
- pub fn with_context<F, R>(f: F) -> R
24
- where
25
- F: FnOnce(&Context) -> R,
26
- {
27
- let context = Context::new();
28
- f(&context)
29
- }
30
-
31
- impl Context {
32
- /// Creates a new test context in a temporary directory
33
- ///
34
- /// # Panics
35
- ///
36
- /// Panics if the temp directory cannot be created.
37
- #[must_use]
38
- pub fn new() -> Self {
39
- let root = tempfile::tempdir().expect("failed to create temp dir");
40
- let absolute_path = fs::canonicalize(root.path()).unwrap();
41
- Self {
42
- _root: root,
43
- absolute_path,
44
- }
45
- }
46
-
47
- /// Returns the absolute path to the temp directory as a `PathBuf`
48
- ///
49
- /// # Panics
50
- ///
51
- /// Panics if the path cannot be canonicalized.
52
- #[must_use]
53
- pub fn absolute_path(&self) -> PathBuf {
54
- self.absolute_path.clone()
55
- }
56
-
57
- /// Returns the absolute path to the relative path
58
- ///
59
- /// # Panics
60
- ///
61
- /// Panics if the path cannot be canonicalized.
62
- #[must_use]
63
- pub fn absolute_path_to(&self, relative: &str) -> PathBuf {
64
- self.absolute_path.join(relative)
65
- }
66
-
67
- /// Returns the path of `absolute` relative to the context root.
68
- ///
69
- /// # Panics
70
- ///
71
- /// Panics if the provided path cannot be canonicalized or is not under the root.
72
- #[must_use]
73
- pub fn relative_path_to<P: AsRef<Path>>(&self, absolute: P) -> PathBuf {
74
- absolute
75
- .as_ref()
76
- .strip_prefix(self.absolute_path())
77
- .unwrap()
78
- .to_path_buf()
79
- }
80
-
81
- /// Create a directory (and parents) relative to the root
82
- ///
83
- /// # Panics
84
- ///
85
- /// Panics if the directory cannot be created.
86
- pub fn mkdir<P: AsRef<Path>>(&self, relative: P) {
87
- let dir = self.absolute_path().join(relative);
88
- fs::create_dir_all(dir).unwrap();
89
- }
90
-
91
- /// Touch a file relative to the root, creating parent directories as needed
92
- ///
93
- /// # Panics
94
- ///
95
- /// Panics if the file cannot be created.
96
- pub fn touch<P: AsRef<Path>>(&self, relative: P) {
97
- self.write(relative, "");
98
- }
99
-
100
- /// Read a file relative to the root
101
- ///
102
- /// # Panics
103
- ///
104
- /// Panics if the file cannot be read.
105
- #[must_use]
106
- pub fn read<P: AsRef<Path>>(&self, relative: P) -> String {
107
- fs::read_to_string(self.absolute_path().join(relative)).unwrap()
108
- }
109
-
110
- /// Write a file relative to the root, creating parent directories as needed
111
- ///
112
- /// # Panics
113
- ///
114
- /// Panics if the file cannot be created.
115
- pub fn write<P: AsRef<Path>>(&self, relative: P, content: &str) {
116
- let path = self.absolute_path().join(relative);
117
- if let Some(parent) = path.parent() {
118
- fs::create_dir_all(parent).unwrap();
119
- }
120
- let content = normalize_indentation(content);
121
- fs::write(path, content).unwrap();
122
- }
123
- }
124
-
125
- impl Default for Context {
126
- fn default() -> Self {
127
- Self::new()
128
- }
129
- }
130
-
131
- // no local normalize_indentation; shared via super::normalize_indentation
132
-
133
- #[cfg(test)]
134
- mod tests {
135
- use super::*;
136
-
137
- #[test]
138
- fn creates_and_cleans_up_temp_dir() {
139
- let context = Context::new();
140
- let root = context.absolute_path();
141
-
142
- assert!(root.exists());
143
-
144
- drop(context);
145
-
146
- // After drop, the directory should not exist anymore
147
- assert!(!root.exists());
148
- }
149
-
150
- #[test]
151
- fn mkdir_creates_directories() {
152
- let context = Context::new();
153
-
154
- assert!(!context.absolute_path_to("foo").exists());
155
- context.mkdir("foo");
156
- assert!(context.absolute_path_to("foo").exists());
157
-
158
- assert!(!context.absolute_path_to("bar/baz").exists());
159
- context.mkdir("bar/baz");
160
- assert!(context.absolute_path_to("bar/baz").exists());
161
- }
162
-
163
- #[test]
164
- fn touch_creates_files() {
165
- let context = Context::new();
166
-
167
- assert!(!context.absolute_path_to("foo/bar.rb").exists());
168
- context.touch("foo/bar.rb");
169
- assert!(context.absolute_path_to("foo/bar.rb").exists());
170
-
171
- assert!(!context.absolute_path_to("baz/qux.rb").exists());
172
- context.touch("baz/qux.rb");
173
- assert!(context.absolute_path_to("baz/qux.rb").exists());
174
- }
175
-
176
- #[test]
177
- fn write_creates_files_with_content() {
178
- let context = Context::new();
179
-
180
- context.write("foo/bar.rb", "class Foo; end\n");
181
- assert_eq!(context.read("foo/bar.rb"), "class Foo; end\n");
182
-
183
- context.write("baz/qux.rb", "class Baz; end\n");
184
- assert_eq!(context.read("baz/qux.rb"), "class Baz; end\n");
185
- }
186
-
187
- #[test]
188
- fn write_creates_files_with_content_and_normalizes_indentation() {
189
- let context = Context::new();
190
-
191
- context.write("foo/bar.rb", {
192
- "
193
- class Foo
194
- def bar
195
- puts 'baz'
196
- end
197
- end
198
- "
199
- });
200
-
201
- assert_eq!(
202
- context.read("foo/bar.rb"),
203
- normalize_indentation({
204
- "
205
- class Foo
206
- def bar
207
- puts 'baz'
208
- end
209
- end
210
- "
211
- }),
212
- );
213
- }
214
-
215
- #[test]
216
- fn with_context_creates_and_cleans_up_temp_dir() {
217
- let root = with_context(|context| {
218
- let root = context.absolute_path();
219
- assert!(root.exists());
220
- context.touch("foo.rb");
221
- root
222
- });
223
-
224
- assert!(!root.exists());
225
- }
226
- }
1
+ use super::normalize_indentation;
2
+ use std::fs;
3
+ use std::path::{Path, PathBuf};
4
+ use tempfile::TempDir;
5
+
6
+ #[derive(Debug)]
7
+ pub struct Context {
8
+ _root: TempDir,
9
+ absolute_path: PathBuf,
10
+ }
11
+
12
+ /// Executes a closure with a new temporary context, ensuring cleanup afterwards.
13
+ ///
14
+ /// # Examples
15
+ ///
16
+ /// ```
17
+ /// use rubydex::test_utils::with_context;
18
+ ///
19
+ /// with_context(|context| {
20
+ /// context.touch("foo.rb");
21
+ /// });
22
+ /// ```
23
+ pub fn with_context<F, R>(f: F) -> R
24
+ where
25
+ F: FnOnce(&Context) -> R,
26
+ {
27
+ let context = Context::new();
28
+ f(&context)
29
+ }
30
+
31
+ impl Context {
32
+ /// Creates a new test context in a temporary directory
33
+ ///
34
+ /// # Panics
35
+ ///
36
+ /// Panics if the temp directory cannot be created.
37
+ #[must_use]
38
+ pub fn new() -> Self {
39
+ let root = tempfile::tempdir().expect("failed to create temp dir");
40
+ let absolute_path = fs::canonicalize(root.path()).unwrap();
41
+ Self {
42
+ _root: root,
43
+ absolute_path,
44
+ }
45
+ }
46
+
47
+ /// Returns the absolute path to the temp directory as a `PathBuf`
48
+ ///
49
+ /// # Panics
50
+ ///
51
+ /// Panics if the path cannot be canonicalized.
52
+ #[must_use]
53
+ pub fn absolute_path(&self) -> PathBuf {
54
+ self.absolute_path.clone()
55
+ }
56
+
57
+ /// Returns the absolute path to the relative path
58
+ ///
59
+ /// # Panics
60
+ ///
61
+ /// Panics if the path cannot be canonicalized.
62
+ #[must_use]
63
+ pub fn absolute_path_to(&self, relative: &str) -> PathBuf {
64
+ self.absolute_path.join(relative)
65
+ }
66
+
67
+ /// Returns the path of `absolute` relative to the context root.
68
+ ///
69
+ /// # Panics
70
+ ///
71
+ /// Panics if the provided path cannot be canonicalized or is not under the root.
72
+ #[must_use]
73
+ pub fn relative_path_to<P: AsRef<Path>>(&self, absolute: P) -> PathBuf {
74
+ absolute
75
+ .as_ref()
76
+ .strip_prefix(self.absolute_path())
77
+ .unwrap()
78
+ .to_path_buf()
79
+ }
80
+
81
+ /// Create a directory (and parents) relative to the root
82
+ ///
83
+ /// # Panics
84
+ ///
85
+ /// Panics if the directory cannot be created.
86
+ pub fn mkdir<P: AsRef<Path>>(&self, relative: P) {
87
+ let dir = self.absolute_path().join(relative);
88
+ fs::create_dir_all(dir).unwrap();
89
+ }
90
+
91
+ /// Touch a file relative to the root, creating parent directories as needed
92
+ ///
93
+ /// # Panics
94
+ ///
95
+ /// Panics if the file cannot be created.
96
+ pub fn touch<P: AsRef<Path>>(&self, relative: P) {
97
+ self.write(relative, "");
98
+ }
99
+
100
+ /// Read a file relative to the root
101
+ ///
102
+ /// # Panics
103
+ ///
104
+ /// Panics if the file cannot be read.
105
+ #[must_use]
106
+ pub fn read<P: AsRef<Path>>(&self, relative: P) -> String {
107
+ fs::read_to_string(self.absolute_path().join(relative)).unwrap()
108
+ }
109
+
110
+ /// Write a file relative to the root, creating parent directories as needed
111
+ ///
112
+ /// # Panics
113
+ ///
114
+ /// Panics if the file cannot be created.
115
+ pub fn write<P: AsRef<Path>>(&self, relative: P, content: &str) {
116
+ let path = self.absolute_path().join(relative);
117
+ if let Some(parent) = path.parent() {
118
+ fs::create_dir_all(parent).unwrap();
119
+ }
120
+ let content = normalize_indentation(content);
121
+ fs::write(path, content).unwrap();
122
+ }
123
+ }
124
+
125
+ impl Default for Context {
126
+ fn default() -> Self {
127
+ Self::new()
128
+ }
129
+ }
130
+
131
+ // no local normalize_indentation; shared via super::normalize_indentation
132
+
133
+ #[cfg(test)]
134
+ mod tests {
135
+ use super::*;
136
+
137
+ #[test]
138
+ fn creates_and_cleans_up_temp_dir() {
139
+ let context = Context::new();
140
+ let root = context.absolute_path();
141
+
142
+ assert!(root.exists());
143
+
144
+ drop(context);
145
+
146
+ // After drop, the directory should not exist anymore
147
+ assert!(!root.exists());
148
+ }
149
+
150
+ #[test]
151
+ fn mkdir_creates_directories() {
152
+ let context = Context::new();
153
+
154
+ assert!(!context.absolute_path_to("foo").exists());
155
+ context.mkdir("foo");
156
+ assert!(context.absolute_path_to("foo").exists());
157
+
158
+ assert!(!context.absolute_path_to("bar/baz").exists());
159
+ context.mkdir("bar/baz");
160
+ assert!(context.absolute_path_to("bar/baz").exists());
161
+ }
162
+
163
+ #[test]
164
+ fn touch_creates_files() {
165
+ let context = Context::new();
166
+
167
+ assert!(!context.absolute_path_to("foo/bar.rb").exists());
168
+ context.touch("foo/bar.rb");
169
+ assert!(context.absolute_path_to("foo/bar.rb").exists());
170
+
171
+ assert!(!context.absolute_path_to("baz/qux.rb").exists());
172
+ context.touch("baz/qux.rb");
173
+ assert!(context.absolute_path_to("baz/qux.rb").exists());
174
+ }
175
+
176
+ #[test]
177
+ fn write_creates_files_with_content() {
178
+ let context = Context::new();
179
+
180
+ context.write("foo/bar.rb", "class Foo; end\n");
181
+ assert_eq!(context.read("foo/bar.rb"), "class Foo; end\n");
182
+
183
+ context.write("baz/qux.rb", "class Baz; end\n");
184
+ assert_eq!(context.read("baz/qux.rb"), "class Baz; end\n");
185
+ }
186
+
187
+ #[test]
188
+ fn write_creates_files_with_content_and_normalizes_indentation() {
189
+ let context = Context::new();
190
+
191
+ context.write("foo/bar.rb", {
192
+ "
193
+ class Foo
194
+ def bar
195
+ puts 'baz'
196
+ end
197
+ end
198
+ "
199
+ });
200
+
201
+ assert_eq!(
202
+ context.read("foo/bar.rb"),
203
+ normalize_indentation({
204
+ "
205
+ class Foo
206
+ def bar
207
+ puts 'baz'
208
+ end
209
+ end
210
+ "
211
+ }),
212
+ );
213
+ }
214
+
215
+ #[test]
216
+ fn with_context_creates_and_cleans_up_temp_dir() {
217
+ let root = with_context(|context| {
218
+ let root = context.absolute_path();
219
+ assert!(root.exists());
220
+ context.touch("foo.rb");
221
+ root
222
+ });
223
+
224
+ assert!(!root.exists());
225
+ }
226
+ }