rubydex 0.2.1 → 0.2.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/ext/rubydex/definition.c +27 -0
- data/ext/rubydex/rubydex.c +2 -0
- data/ext/rubydex/signature.c +83 -0
- data/ext/rubydex/signature.h +23 -0
- data/lib/rubydex/signature.rb +130 -0
- data/lib/rubydex/version.rb +1 -1
- data/lib/rubydex.rb +1 -0
- data/rust/rubydex/src/indexing/ruby_indexer.rs +73 -10
- data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +2818 -2656
- data/rust/rubydex/src/model/definitions.rs +23 -0
- data/rust/rubydex/src/model/graph.rs +40 -12
- data/rust/rubydex/src/query.rs +598 -1
- data/rust/rubydex/src/resolution.rs +30 -11
- data/rust/rubydex/src/resolution_tests.rs +155 -1
- data/rust/rubydex-sys/src/declaration_api.rs +10 -33
- data/rust/rubydex-sys/src/lib.rs +1 -0
- data/rust/rubydex-sys/src/signature_api.rs +209 -0
- metadata +6 -2
|
@@ -4926,6 +4926,25 @@ mod visibility_resolution_tests {
|
|
|
4926
4926
|
};
|
|
4927
4927
|
}
|
|
4928
4928
|
|
|
4929
|
+
#[test]
|
|
4930
|
+
fn retroactive_visibility_override_applies_in_source_order() {
|
|
4931
|
+
let mut context = GraphTest::new();
|
|
4932
|
+
context.index_uri(
|
|
4933
|
+
"file:///foo.rb",
|
|
4934
|
+
r"
|
|
4935
|
+
class Foo
|
|
4936
|
+
def bar; end
|
|
4937
|
+
private :bar
|
|
4938
|
+
public :bar
|
|
4939
|
+
end
|
|
4940
|
+
",
|
|
4941
|
+
);
|
|
4942
|
+
context.resolve();
|
|
4943
|
+
|
|
4944
|
+
assert_no_diagnostics!(&context);
|
|
4945
|
+
assert_visibility_eq!(context, "Foo#bar()", Visibility::Public);
|
|
4946
|
+
}
|
|
4947
|
+
|
|
4929
4948
|
#[test]
|
|
4930
4949
|
fn retroactive_visibility_on_direct_method() {
|
|
4931
4950
|
let mut context = GraphTest::new();
|
|
@@ -5066,7 +5085,7 @@ mod visibility_resolution_tests {
|
|
|
5066
5085
|
assert_diagnostics_eq!(
|
|
5067
5086
|
context,
|
|
5068
5087
|
&[
|
|
5069
|
-
"undefined-method-visibility-target: undefined method `nonexistent()` for visibility change
|
|
5088
|
+
"undefined-method-visibility-target: undefined method `Foo#nonexistent()` for visibility change (2:12-2:23)"
|
|
5070
5089
|
]
|
|
5071
5090
|
);
|
|
5072
5091
|
}
|
|
@@ -5306,4 +5325,139 @@ mod visibility_resolution_tests {
|
|
|
5306
5325
|
|
|
5307
5326
|
assert_visibility_eq!(context, "Foo::BAR", Visibility::Private);
|
|
5308
5327
|
}
|
|
5328
|
+
|
|
5329
|
+
#[test]
|
|
5330
|
+
fn retroactive_singleton_method_visibility_on_direct_member() {
|
|
5331
|
+
let mut context = GraphTest::new();
|
|
5332
|
+
context.index_uri(
|
|
5333
|
+
"file:///foo.rb",
|
|
5334
|
+
r"
|
|
5335
|
+
class Foo
|
|
5336
|
+
def self.bar; end
|
|
5337
|
+
def self.baz; end
|
|
5338
|
+
|
|
5339
|
+
private_class_method :bar
|
|
5340
|
+
private_class_method :baz
|
|
5341
|
+
public_class_method :baz
|
|
5342
|
+
end
|
|
5343
|
+
",
|
|
5344
|
+
);
|
|
5345
|
+
context.resolve();
|
|
5346
|
+
|
|
5347
|
+
assert_no_diagnostics!(&context);
|
|
5348
|
+
assert_visibility_eq!(context, "Foo::<Foo>#bar()", Visibility::Private);
|
|
5349
|
+
assert_visibility_eq!(context, "Foo::<Foo>#baz()", Visibility::Public);
|
|
5350
|
+
}
|
|
5351
|
+
|
|
5352
|
+
#[test]
|
|
5353
|
+
fn retroactive_singleton_method_visibility_on_inherited_method() {
|
|
5354
|
+
let mut context = GraphTest::new();
|
|
5355
|
+
context.index_uri(
|
|
5356
|
+
"file:///foo.rb",
|
|
5357
|
+
r"
|
|
5358
|
+
class Parent
|
|
5359
|
+
def self.foo; end
|
|
5360
|
+
end
|
|
5361
|
+
|
|
5362
|
+
class Child < Parent
|
|
5363
|
+
private_class_method :foo
|
|
5364
|
+
end
|
|
5365
|
+
",
|
|
5366
|
+
);
|
|
5367
|
+
context.resolve();
|
|
5368
|
+
|
|
5369
|
+
assert_no_diagnostics!(&context);
|
|
5370
|
+
assert_declaration_exists!(context, "Child::<Child>#foo()");
|
|
5371
|
+
assert_visibility_eq!(context, "Child::<Child>#foo()", Visibility::Private);
|
|
5372
|
+
assert_visibility_eq!(context, "Parent::<Parent>#foo()", Visibility::Public);
|
|
5373
|
+
}
|
|
5374
|
+
|
|
5375
|
+
#[test]
|
|
5376
|
+
fn retroactive_singleton_method_visibility_on_undefined_method_emits_diagnostic() {
|
|
5377
|
+
let mut context = GraphTest::new();
|
|
5378
|
+
context.index_uri(
|
|
5379
|
+
"file:///foo.rb",
|
|
5380
|
+
r"
|
|
5381
|
+
class Foo
|
|
5382
|
+
private_class_method :nonexistent
|
|
5383
|
+
end
|
|
5384
|
+
",
|
|
5385
|
+
);
|
|
5386
|
+
context.resolve();
|
|
5387
|
+
|
|
5388
|
+
assert_diagnostics_eq!(
|
|
5389
|
+
context,
|
|
5390
|
+
&[
|
|
5391
|
+
"undefined-method-visibility-target: undefined method `Foo::<Foo>#nonexistent()` for visibility change (2:25-2:36)"
|
|
5392
|
+
]
|
|
5393
|
+
);
|
|
5394
|
+
}
|
|
5395
|
+
|
|
5396
|
+
#[test]
|
|
5397
|
+
fn retroactive_singleton_method_visibility_undefined_target_diagnostic_clears_when_file_deleted() {
|
|
5398
|
+
let mut context = GraphTest::new();
|
|
5399
|
+
context.index_uri(
|
|
5400
|
+
"file:///foo.rb",
|
|
5401
|
+
r"
|
|
5402
|
+
class Foo
|
|
5403
|
+
end
|
|
5404
|
+
",
|
|
5405
|
+
);
|
|
5406
|
+
context.index_uri(
|
|
5407
|
+
"file:///bad.rb",
|
|
5408
|
+
r"
|
|
5409
|
+
class Foo
|
|
5410
|
+
private_class_method :missing
|
|
5411
|
+
end
|
|
5412
|
+
",
|
|
5413
|
+
);
|
|
5414
|
+
context.resolve();
|
|
5415
|
+
|
|
5416
|
+
assert_diagnostics_eq!(
|
|
5417
|
+
context,
|
|
5418
|
+
&[
|
|
5419
|
+
"undefined-method-visibility-target: undefined method `Foo::<Foo>#missing()` for visibility change (2:25-2:32)"
|
|
5420
|
+
]
|
|
5421
|
+
);
|
|
5422
|
+
|
|
5423
|
+
context.delete_uri("file:///bad.rb");
|
|
5424
|
+
context.resolve();
|
|
5425
|
+
|
|
5426
|
+
assert_no_diagnostics!(&context);
|
|
5427
|
+
}
|
|
5428
|
+
|
|
5429
|
+
#[test]
|
|
5430
|
+
fn retroactive_singleton_method_visibility_undefined_target_diagnostic_clears_when_target_added() {
|
|
5431
|
+
let mut context = GraphTest::new();
|
|
5432
|
+
context.index_uri(
|
|
5433
|
+
"file:///foo.rb",
|
|
5434
|
+
r"
|
|
5435
|
+
class Foo
|
|
5436
|
+
private_class_method :missing
|
|
5437
|
+
end
|
|
5438
|
+
",
|
|
5439
|
+
);
|
|
5440
|
+
context.resolve();
|
|
5441
|
+
|
|
5442
|
+
assert_diagnostics_eq!(
|
|
5443
|
+
context,
|
|
5444
|
+
&[
|
|
5445
|
+
"undefined-method-visibility-target: undefined method `Foo::<Foo>#missing()` for visibility change (2:25-2:32)"
|
|
5446
|
+
]
|
|
5447
|
+
);
|
|
5448
|
+
|
|
5449
|
+
context.index_uri(
|
|
5450
|
+
"file:///foo.rb",
|
|
5451
|
+
r"
|
|
5452
|
+
class Foo
|
|
5453
|
+
def self.missing; end
|
|
5454
|
+
private_class_method :missing
|
|
5455
|
+
end
|
|
5456
|
+
",
|
|
5457
|
+
);
|
|
5458
|
+
context.resolve();
|
|
5459
|
+
|
|
5460
|
+
assert_no_diagnostics!(&context);
|
|
5461
|
+
assert_visibility_eq!(context, "Foo::<Foo>#missing()", Visibility::Private);
|
|
5462
|
+
}
|
|
5309
5463
|
}
|
|
@@ -197,42 +197,19 @@ pub unsafe extern "C" fn rdx_declaration_find_member(
|
|
|
197
197
|
|
|
198
198
|
with_graph(pointer, |graph| {
|
|
199
199
|
let id = DeclarationId::new(declaration_id);
|
|
200
|
+
let member_id = StringId::from(member_str.as_str());
|
|
200
201
|
|
|
201
|
-
let
|
|
202
|
-
|
|
202
|
+
let member_decl_id = match rubydex::query::find_member_in_ancestors(graph, id, member_id, only_inherited) {
|
|
203
|
+
Ok(decl_id) => decl_id,
|
|
204
|
+
Err(rubydex::query::FindMemberError::MemberNotFound) => return ptr::null(),
|
|
205
|
+
Err(err) => unreachable!(
|
|
206
|
+
"Namespace#find_member is only exposed on namespace declarations, so the declaration must exist and be \
|
|
207
|
+
a namespace, got {err:?}"
|
|
208
|
+
),
|
|
203
209
|
};
|
|
204
210
|
|
|
205
|
-
let
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
decl.ancestors()
|
|
209
|
-
.iter()
|
|
210
|
-
.find_map(|ancestor| match ancestor {
|
|
211
|
-
Ancestor::Complete(ancestor_id) => {
|
|
212
|
-
// When only_inherited, skip self and prepended modules
|
|
213
|
-
if only_inherited {
|
|
214
|
-
let is_self = *ancestor_id == id;
|
|
215
|
-
if is_self {
|
|
216
|
-
found_main_namespace = true;
|
|
217
|
-
}
|
|
218
|
-
if is_self || !found_main_namespace {
|
|
219
|
-
return None;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
let ancestor_decl = graph.declarations().get(ancestor_id).unwrap().as_namespace().unwrap();
|
|
224
|
-
|
|
225
|
-
if let Some(member_decl_id) = ancestor_decl.member(&member_id) {
|
|
226
|
-
return Some((member_decl_id, graph.declarations().get(member_decl_id).unwrap()));
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
None
|
|
230
|
-
}
|
|
231
|
-
Ancestor::Partial(_) => None,
|
|
232
|
-
})
|
|
233
|
-
.map_or(ptr::null(), |(member_decl_id, member_decl)| {
|
|
234
|
-
Box::into_raw(Box::new(CDeclaration::from_declaration(*member_decl_id, member_decl))).cast_const()
|
|
235
|
-
})
|
|
211
|
+
let member_decl = graph.declarations().get(&member_decl_id).unwrap();
|
|
212
|
+
Box::into_raw(Box::new(CDeclaration::from_declaration(member_decl_id, member_decl))).cast_const()
|
|
236
213
|
})
|
|
237
214
|
}
|
|
238
215
|
|
data/rust/rubydex-sys/src/lib.rs
CHANGED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
//! C API for method signature accessors
|
|
2
|
+
|
|
3
|
+
use crate::graph_api::{GraphPointer, with_graph};
|
|
4
|
+
use crate::location_api::{Location, create_location_for_uri_and_offset};
|
|
5
|
+
use libc::c_char;
|
|
6
|
+
use rubydex::model::declaration::Declaration;
|
|
7
|
+
use rubydex::model::definitions::{Definition, MethodDefinition, Parameter};
|
|
8
|
+
use rubydex::model::graph::Graph;
|
|
9
|
+
use rubydex::model::ids::DefinitionId;
|
|
10
|
+
use std::ffi::CString;
|
|
11
|
+
use std::ptr;
|
|
12
|
+
|
|
13
|
+
/// C-compatible enum representing the kind of a parameter.
|
|
14
|
+
#[repr(C)]
|
|
15
|
+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
16
|
+
pub enum ParameterKind {
|
|
17
|
+
RequiredPositional = 0,
|
|
18
|
+
OptionalPositional = 1,
|
|
19
|
+
RestPositional = 2,
|
|
20
|
+
Post = 3,
|
|
21
|
+
RequiredKeyword = 4,
|
|
22
|
+
OptionalKeyword = 5,
|
|
23
|
+
RestKeyword = 6,
|
|
24
|
+
Forward = 7,
|
|
25
|
+
Block = 8,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
fn map_parameter_kind(param: &Parameter) -> ParameterKind {
|
|
29
|
+
match param {
|
|
30
|
+
Parameter::RequiredPositional(_) => ParameterKind::RequiredPositional,
|
|
31
|
+
Parameter::Post(_) => ParameterKind::Post,
|
|
32
|
+
Parameter::OptionalPositional(_) => ParameterKind::OptionalPositional,
|
|
33
|
+
Parameter::RestPositional(_) => ParameterKind::RestPositional,
|
|
34
|
+
Parameter::RequiredKeyword(_) => ParameterKind::RequiredKeyword,
|
|
35
|
+
Parameter::OptionalKeyword(_) => ParameterKind::OptionalKeyword,
|
|
36
|
+
Parameter::RestKeyword(_) => ParameterKind::RestKeyword,
|
|
37
|
+
Parameter::Block(_) => ParameterKind::Block,
|
|
38
|
+
Parameter::Forward(_) => ParameterKind::Forward,
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/// C-compatible struct representing a single parameter with its name, kind, and location.
|
|
43
|
+
#[repr(C)]
|
|
44
|
+
pub struct ParameterEntry {
|
|
45
|
+
pub name: *const c_char,
|
|
46
|
+
pub location: *mut Location,
|
|
47
|
+
pub kind: ParameterKind,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/// C-compatible struct representing a single method signature (a list of parameters).
|
|
51
|
+
#[repr(C)]
|
|
52
|
+
pub struct SignatureEntry {
|
|
53
|
+
pub parameters: *mut ParameterEntry,
|
|
54
|
+
pub parameters_len: usize,
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/// C-compatible array of signatures.
|
|
58
|
+
#[repr(C)]
|
|
59
|
+
pub struct SignatureArray {
|
|
60
|
+
pub items: *mut SignatureEntry,
|
|
61
|
+
pub len: usize,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/// Returns a newly allocated array of signatures for the given method definition id.
|
|
65
|
+
/// Caller must free the returned pointer with `rdx_definition_signatures_free`.
|
|
66
|
+
///
|
|
67
|
+
/// # Safety
|
|
68
|
+
/// - `pointer` must be a valid pointer previously returned by `rdx_graph_new`.
|
|
69
|
+
/// - `definition_id` must be a valid definition id.
|
|
70
|
+
///
|
|
71
|
+
/// # Panics
|
|
72
|
+
/// Panics if `definition_id` does not exist or is not a `MethodDefinition`.
|
|
73
|
+
#[unsafe(no_mangle)]
|
|
74
|
+
pub unsafe extern "C" fn rdx_definition_signatures(pointer: GraphPointer, definition_id: u64) -> *mut SignatureArray {
|
|
75
|
+
with_graph(pointer, |graph| {
|
|
76
|
+
let def_id = DefinitionId::new(definition_id);
|
|
77
|
+
let Definition::Method(method_def) = graph.definitions().get(&def_id).expect("definition should exist") else {
|
|
78
|
+
panic!("expected a method definition");
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
let sig_entries = collect_method_signatures(graph, method_def);
|
|
82
|
+
|
|
83
|
+
let len = sig_entries.len();
|
|
84
|
+
let items_ptr = Box::into_raw(sig_entries.into_boxed_slice()).cast::<SignatureEntry>();
|
|
85
|
+
|
|
86
|
+
Box::into_raw(Box::new(SignatureArray { items: items_ptr, len }))
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/// Helper: build signature entries from a `MethodDefinition`.
|
|
91
|
+
fn collect_method_signatures(graph: &Graph, method_def: &MethodDefinition) -> Vec<SignatureEntry> {
|
|
92
|
+
let uri_id = *method_def.uri_id();
|
|
93
|
+
let document = graph.documents().get(&uri_id).expect("document should exist");
|
|
94
|
+
|
|
95
|
+
method_def
|
|
96
|
+
.signatures()
|
|
97
|
+
.as_slice()
|
|
98
|
+
.iter()
|
|
99
|
+
.map(|sig| {
|
|
100
|
+
let param_entries: Vec<ParameterEntry> = sig
|
|
101
|
+
.iter()
|
|
102
|
+
.map(|param| {
|
|
103
|
+
let param_struct = param.inner();
|
|
104
|
+
let name = graph
|
|
105
|
+
.strings()
|
|
106
|
+
.get(param_struct.str())
|
|
107
|
+
.expect("parameter name string should exist");
|
|
108
|
+
let name_str = CString::new(name.as_str()).unwrap().into_raw().cast_const();
|
|
109
|
+
|
|
110
|
+
ParameterEntry {
|
|
111
|
+
name: name_str,
|
|
112
|
+
kind: map_parameter_kind(param),
|
|
113
|
+
location: create_location_for_uri_and_offset(graph, document, param_struct.offset()),
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
.collect();
|
|
117
|
+
|
|
118
|
+
let parameters_len = param_entries.len();
|
|
119
|
+
let parameters_ptr = Box::into_raw(param_entries.into_boxed_slice()).cast::<ParameterEntry>();
|
|
120
|
+
|
|
121
|
+
SignatureEntry {
|
|
122
|
+
parameters: parameters_ptr,
|
|
123
|
+
parameters_len,
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
.collect()
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/// Returns signatures for a `MethodAliasDefinition` by following the alias chain.
|
|
130
|
+
/// Always returns a valid `SignatureArray` pointer (possibly with `len == 0`).
|
|
131
|
+
/// Errors during alias resolution (unresolved receivers, circular chains, etc.)
|
|
132
|
+
/// are silently ignored.
|
|
133
|
+
///
|
|
134
|
+
/// # Safety
|
|
135
|
+
/// - `pointer` must be a valid pointer previously returned by `rdx_graph_new`.
|
|
136
|
+
/// - `definition_id` must be a valid definition id.
|
|
137
|
+
///
|
|
138
|
+
/// # Panics
|
|
139
|
+
/// Panics if `definition_id` does not exist or is not a `MethodAliasDefinition`.
|
|
140
|
+
#[unsafe(no_mangle)]
|
|
141
|
+
pub unsafe extern "C" fn rdx_method_alias_definition_signatures(
|
|
142
|
+
pointer: GraphPointer,
|
|
143
|
+
definition_id: u64,
|
|
144
|
+
) -> *mut SignatureArray {
|
|
145
|
+
with_graph(pointer, |graph| {
|
|
146
|
+
let def_id = DefinitionId::new(definition_id);
|
|
147
|
+
let resolved = rubydex::query::follow_method_alias(graph, def_id);
|
|
148
|
+
|
|
149
|
+
let mut sig_entries: Vec<SignatureEntry> = Vec::new();
|
|
150
|
+
|
|
151
|
+
if let Ok(declaration_id) = resolved {
|
|
152
|
+
if let Some(Declaration::Method(method_def)) = graph.declarations().get(&declaration_id) {
|
|
153
|
+
for definition_id in method_def.definitions() {
|
|
154
|
+
if let Some(Definition::Method(method_definition)) = graph.definitions().get(definition_id) {
|
|
155
|
+
sig_entries.extend(collect_method_signatures(graph, method_definition));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
panic!("expected a method declaration");
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
let mut boxed = sig_entries.into_boxed_slice();
|
|
164
|
+
let len = boxed.len();
|
|
165
|
+
let items_ptr = boxed.as_mut_ptr();
|
|
166
|
+
std::mem::forget(boxed);
|
|
167
|
+
|
|
168
|
+
Box::into_raw(Box::new(SignatureArray { items: items_ptr, len }))
|
|
169
|
+
})
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/// Frees a `SignatureArray` previously returned by `rdx_definition_signatures`.
|
|
173
|
+
///
|
|
174
|
+
/// # Safety
|
|
175
|
+
/// - `ptr` must be a valid pointer previously returned by `rdx_definition_signatures`.
|
|
176
|
+
/// - `ptr` must not be used after being freed.
|
|
177
|
+
#[unsafe(no_mangle)]
|
|
178
|
+
pub unsafe extern "C" fn rdx_definition_signatures_free(ptr: *mut SignatureArray) {
|
|
179
|
+
if ptr.is_null() {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
let arr = unsafe { Box::from_raw(ptr) };
|
|
184
|
+
|
|
185
|
+
if arr.items.is_null() || arr.len == 0 {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
let slice_ptr = ptr::slice_from_raw_parts_mut(arr.items, arr.len);
|
|
190
|
+
let sig_slice: Box<[SignatureEntry]> = unsafe { Box::from_raw(slice_ptr) };
|
|
191
|
+
|
|
192
|
+
for sig_entry in &*sig_slice {
|
|
193
|
+
if sig_entry.parameters.is_null() || sig_entry.parameters_len == 0 {
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
let param_slice_ptr = ptr::slice_from_raw_parts_mut(sig_entry.parameters, sig_entry.parameters_len);
|
|
198
|
+
let param_slice: Box<[ParameterEntry]> = unsafe { Box::from_raw(param_slice_ptr) };
|
|
199
|
+
|
|
200
|
+
for param_entry in &*param_slice {
|
|
201
|
+
if !param_entry.name.is_null() {
|
|
202
|
+
drop(unsafe { CString::from_raw(param_entry.name.cast_mut()) });
|
|
203
|
+
}
|
|
204
|
+
if !param_entry.location.is_null() {
|
|
205
|
+
unsafe { crate::location_api::rdx_location_free(param_entry.location) };
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rubydex
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shopify
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-05-
|
|
11
|
+
date: 2026-05-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: A high-performance static analysis suite for Ruby, built in Rust with
|
|
14
14
|
Ruby APIs
|
|
@@ -41,6 +41,8 @@ files:
|
|
|
41
41
|
- ext/rubydex/reference.c
|
|
42
42
|
- ext/rubydex/reference.h
|
|
43
43
|
- ext/rubydex/rubydex.c
|
|
44
|
+
- ext/rubydex/signature.c
|
|
45
|
+
- ext/rubydex/signature.h
|
|
44
46
|
- ext/rubydex/utils.c
|
|
45
47
|
- ext/rubydex/utils.h
|
|
46
48
|
- lib/rubydex.rb
|
|
@@ -53,6 +55,7 @@ files:
|
|
|
53
55
|
- lib/rubydex/keyword_parameter.rb
|
|
54
56
|
- lib/rubydex/location.rb
|
|
55
57
|
- lib/rubydex/mixin.rb
|
|
58
|
+
- lib/rubydex/signature.rb
|
|
56
59
|
- lib/rubydex/version.rb
|
|
57
60
|
- rbi/rubydex.rbi
|
|
58
61
|
- rust/Cargo.lock
|
|
@@ -77,6 +80,7 @@ files:
|
|
|
77
80
|
- rust/rubydex-sys/src/location_api.rs
|
|
78
81
|
- rust/rubydex-sys/src/name_api.rs
|
|
79
82
|
- rust/rubydex-sys/src/reference_api.rs
|
|
83
|
+
- rust/rubydex-sys/src/signature_api.rs
|
|
80
84
|
- rust/rubydex-sys/src/utils.rs
|
|
81
85
|
- rust/rubydex/Cargo.toml
|
|
82
86
|
- rust/rubydex/src/compile_assertions.rs
|