method-ray 0.1.1 → 0.1.2
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/CHANGELOG.md +12 -0
- data/ext/src/lib.rs +15 -0
- data/lib/methodray/version.rb +1 -1
- data/rust/Cargo.toml +3 -0
- data/rust/src/cache/rbs_cache.rs +145 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b03f7efedd583d2cda9e59cd651ded78d5357c53eb06eac8980aae25db0529de
|
|
4
|
+
data.tar.gz: c02996cc2a511f800d34cec0ce46744c6ae2bddb8974e361f994a332b898c467
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3aa19e8a26274f5d8c7b5b746e67f10d4e47ac281852251c737ebed4f933b5426e8b842d575f26110ee279fc48079a1dc382e78b2a184e0d4211d241dabae77a
|
|
7
|
+
data.tar.gz: '08e6b8bf49475c874538c007b52fec615459eb0c376357e1b2429868a67885eb695d261ba02d078b7fb0835321b92e84f06a6ac5366066379229b0e78072d786'
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.1.2] - 2025-01-19
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Pre-built RBS cache bundled with gem (no initialization required)
|
|
13
|
+
- `MethodRay.setup` for cache generation (internal API)
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Separated `setup` logic from `infer_types` for cleaner cache generation
|
|
18
|
+
|
|
8
19
|
## [0.1.1] - 2025-01-19
|
|
9
20
|
|
|
10
21
|
### Added
|
|
@@ -19,5 +30,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
19
30
|
- Initial release
|
|
20
31
|
- `methodray check` - Static type checking for Ruby files
|
|
21
32
|
|
|
33
|
+
[0.1.2]: https://github.com/dak2/method-ray/releases/tag/v0.1.2
|
|
22
34
|
[0.1.1]: https://github.com/dak2/method-ray/releases/tag/v0.1.1
|
|
23
35
|
[0.1.0]: https://github.com/dak2/method-ray/releases/tag/v0.1.0
|
data/ext/src/lib.rs
CHANGED
|
@@ -66,6 +66,18 @@ impl Analyzer {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/// Setup function that only generates RBS cache
|
|
70
|
+
/// This is used during gem build to pre-generate the cache
|
|
71
|
+
fn setup() -> Result<String, Error> {
|
|
72
|
+
let ruby = unsafe { Ruby::get_unchecked() };
|
|
73
|
+
let mut genv = GlobalEnv::new();
|
|
74
|
+
|
|
75
|
+
// This will load RBS and save to cache if not already cached
|
|
76
|
+
let count = rbs::register_rbs_methods(&mut genv, &ruby)?;
|
|
77
|
+
|
|
78
|
+
Ok(format!("RBS cache generated with {} methods", count))
|
|
79
|
+
}
|
|
80
|
+
|
|
69
81
|
#[magnus::init]
|
|
70
82
|
fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
71
83
|
let module = ruby.define_module("MethodRay")?;
|
|
@@ -75,5 +87,8 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
75
87
|
class.define_method("version", method!(Analyzer::version, 0))?;
|
|
76
88
|
class.define_method("infer_types", method!(Analyzer::infer_types, 1))?;
|
|
77
89
|
|
|
90
|
+
// Module-level setup function for cache generation
|
|
91
|
+
module.define_singleton_method("setup", function!(setup, 0))?;
|
|
92
|
+
|
|
78
93
|
Ok(())
|
|
79
94
|
}
|
data/lib/methodray/version.rb
CHANGED
data/rust/Cargo.toml
CHANGED
data/rust/src/cache/rbs_cache.rs
CHANGED
|
@@ -39,7 +39,7 @@ impl SerializableMethodInfo {
|
|
|
39
39
|
|
|
40
40
|
#[allow(dead_code)]
|
|
41
41
|
impl RbsCache {
|
|
42
|
-
/// Get cache file path
|
|
42
|
+
/// Get user cache file path (in ~/.cache/methodray/)
|
|
43
43
|
pub fn cache_path() -> Result<PathBuf> {
|
|
44
44
|
let cache_dir = dirs::cache_dir()
|
|
45
45
|
.context("Failed to get cache directory")?
|
|
@@ -50,8 +50,42 @@ impl RbsCache {
|
|
|
50
50
|
Ok(cache_dir.join("rbs_cache.bin"))
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
/// Get bundled cache path (shipped with gem)
|
|
54
|
+
///
|
|
55
|
+
/// Gem structure after install:
|
|
56
|
+
/// lib/methodray/
|
|
57
|
+
/// methodray-cli # CLI binary
|
|
58
|
+
/// methodray.bundle # FFI extension (macOS) or methodray.so (Linux)
|
|
59
|
+
/// rbs_cache.bin # Pre-built cache
|
|
60
|
+
///
|
|
61
|
+
/// The CLI binary and cache are in the same directory.
|
|
62
|
+
fn bundled_cache_path() -> Option<PathBuf> {
|
|
63
|
+
if let Ok(exe_path) = std::env::current_exe() {
|
|
64
|
+
if let Some(exe_dir) = exe_path.parent() {
|
|
65
|
+
// Cache is in the same directory as CLI binary
|
|
66
|
+
let bundled = exe_dir.join("rbs_cache.bin");
|
|
67
|
+
if bundled.exists() {
|
|
68
|
+
return Some(bundled);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
None
|
|
73
|
+
}
|
|
74
|
+
|
|
53
75
|
/// Load cache from disk
|
|
76
|
+
/// Tries bundled cache first, then user cache
|
|
54
77
|
pub fn load() -> Result<Self> {
|
|
78
|
+
// Try bundled cache first (shipped with gem)
|
|
79
|
+
if let Some(bundled_path) = Self::bundled_cache_path() {
|
|
80
|
+
if let Ok(bytes) = fs::read(&bundled_path) {
|
|
81
|
+
if let Ok(cache) = bincode::deserialize::<Self>(&bytes) {
|
|
82
|
+
eprintln!("Loaded bundled cache from {}", bundled_path.display());
|
|
83
|
+
return Ok(cache);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Fall back to user cache
|
|
55
89
|
let path = Self::cache_path()?;
|
|
56
90
|
let bytes = fs::read(&path)
|
|
57
91
|
.with_context(|| format!("Failed to read cache from {}", path.display()))?;
|
|
@@ -121,6 +155,7 @@ impl RbsCache {
|
|
|
121
155
|
#[cfg(test)]
|
|
122
156
|
mod tests {
|
|
123
157
|
use super::*;
|
|
158
|
+
use tempfile::tempdir;
|
|
124
159
|
|
|
125
160
|
#[test]
|
|
126
161
|
fn test_cache_serialization() {
|
|
@@ -155,4 +190,113 @@ mod tests {
|
|
|
155
190
|
assert!(!cache.is_valid("0.2.0", "3.7.0"));
|
|
156
191
|
assert!(!cache.is_valid("0.1.0", "3.8.0"));
|
|
157
192
|
}
|
|
193
|
+
|
|
194
|
+
#[test]
|
|
195
|
+
fn test_serializable_method_info_return_type() {
|
|
196
|
+
let method_info = SerializableMethodInfo {
|
|
197
|
+
receiver_class: "String".to_string(),
|
|
198
|
+
method_name: "upcase".to_string(),
|
|
199
|
+
return_type_str: "String".to_string(),
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
let return_type = method_info.return_type();
|
|
203
|
+
assert_eq!(return_type.show(), "String");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
#[test]
|
|
207
|
+
fn test_cache_methods_accessor() {
|
|
208
|
+
let cache = RbsCache {
|
|
209
|
+
version: "0.1.0".to_string(),
|
|
210
|
+
rbs_version: "3.7.0".to_string(),
|
|
211
|
+
methods: vec![
|
|
212
|
+
SerializableMethodInfo {
|
|
213
|
+
receiver_class: "String".to_string(),
|
|
214
|
+
method_name: "upcase".to_string(),
|
|
215
|
+
return_type_str: "String".to_string(),
|
|
216
|
+
},
|
|
217
|
+
SerializableMethodInfo {
|
|
218
|
+
receiver_class: "Integer".to_string(),
|
|
219
|
+
method_name: "to_s".to_string(),
|
|
220
|
+
return_type_str: "String".to_string(),
|
|
221
|
+
},
|
|
222
|
+
],
|
|
223
|
+
timestamp: SystemTime::now(),
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
let methods = cache.methods();
|
|
227
|
+
assert_eq!(methods.len(), 2);
|
|
228
|
+
assert_eq!(methods[0].receiver_class, "String");
|
|
229
|
+
assert_eq!(methods[0].method_name, "upcase");
|
|
230
|
+
assert_eq!(methods[1].receiver_class, "Integer");
|
|
231
|
+
assert_eq!(methods[1].method_name, "to_s");
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
#[test]
|
|
235
|
+
fn test_cache_save_and_load() {
|
|
236
|
+
let temp_dir = tempdir().unwrap();
|
|
237
|
+
let cache_path = temp_dir.path().join("test_cache.bin");
|
|
238
|
+
|
|
239
|
+
let original_cache = RbsCache {
|
|
240
|
+
version: "0.1.0".to_string(),
|
|
241
|
+
rbs_version: "3.7.0".to_string(),
|
|
242
|
+
methods: vec![
|
|
243
|
+
SerializableMethodInfo {
|
|
244
|
+
receiver_class: "String".to_string(),
|
|
245
|
+
method_name: "upcase".to_string(),
|
|
246
|
+
return_type_str: "String".to_string(),
|
|
247
|
+
},
|
|
248
|
+
SerializableMethodInfo {
|
|
249
|
+
receiver_class: "Array".to_string(),
|
|
250
|
+
method_name: "first".to_string(),
|
|
251
|
+
return_type_str: "Object".to_string(),
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
timestamp: SystemTime::now(),
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
// Save to temp file
|
|
258
|
+
let bytes = bincode::serialize(&original_cache).unwrap();
|
|
259
|
+
fs::write(&cache_path, &bytes).unwrap();
|
|
260
|
+
|
|
261
|
+
// Load from temp file
|
|
262
|
+
let loaded_bytes = fs::read(&cache_path).unwrap();
|
|
263
|
+
let loaded_cache: RbsCache = bincode::deserialize(&loaded_bytes).unwrap();
|
|
264
|
+
|
|
265
|
+
assert_eq!(loaded_cache.version, "0.1.0");
|
|
266
|
+
assert_eq!(loaded_cache.rbs_version, "3.7.0");
|
|
267
|
+
assert_eq!(loaded_cache.methods.len(), 2);
|
|
268
|
+
assert_eq!(loaded_cache.methods[0].method_name, "upcase");
|
|
269
|
+
assert_eq!(loaded_cache.methods[1].method_name, "first");
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
#[test]
|
|
273
|
+
fn test_cache_with_empty_methods() {
|
|
274
|
+
let cache = RbsCache {
|
|
275
|
+
version: "0.1.0".to_string(),
|
|
276
|
+
rbs_version: "3.7.0".to_string(),
|
|
277
|
+
methods: vec![],
|
|
278
|
+
timestamp: SystemTime::now(),
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
let bytes = bincode::serialize(&cache).unwrap();
|
|
282
|
+
let deserialized: RbsCache = bincode::deserialize(&bytes).unwrap();
|
|
283
|
+
|
|
284
|
+
assert_eq!(deserialized.methods.len(), 0);
|
|
285
|
+
assert!(deserialized.is_valid("0.1.0", "3.7.0"));
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
#[test]
|
|
289
|
+
fn test_cache_validation_version_mismatch() {
|
|
290
|
+
let cache = RbsCache {
|
|
291
|
+
version: "0.1.0".to_string(),
|
|
292
|
+
rbs_version: "3.7.0".to_string(),
|
|
293
|
+
methods: vec![],
|
|
294
|
+
timestamp: SystemTime::now(),
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
// Both versions must match
|
|
298
|
+
assert!(!cache.is_valid("0.1.1", "3.7.0"));
|
|
299
|
+
assert!(!cache.is_valid("0.1.0", "3.7.1"));
|
|
300
|
+
assert!(!cache.is_valid("0.2.0", "4.0.0"));
|
|
301
|
+
}
|
|
158
302
|
}
|