rubydex 0.1.0.beta13 → 0.2.0
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/exe/rdx +28 -24
- data/ext/rubydex/declaration.c +23 -0
- data/ext/rubydex/extconf.rb +13 -7
- data/ext/rubydex/graph.c +19 -0
- data/ext/rubydex/reference.c +23 -0
- data/lib/rubydex/version.rb +1 -1
- data/rbi/rubydex.rbi +9 -0
- data/rust/rubydex/src/diagnostic.rs +1 -0
- data/rust/rubydex/src/indexing/ruby_indexer.rs +4 -1
- data/rust/rubydex/src/indexing/ruby_indexer_tests.rs +13 -0
- data/rust/rubydex/src/model/graph.rs +41 -2
- data/rust/rubydex/src/query.rs +1 -1
- data/rust/rubydex/src/resolution.rs +90 -2
- data/rust/rubydex/src/resolution_tests.rs +4627 -4197
- data/rust/rubydex-sys/src/declaration_api.rs +28 -0
- data/rust/rubydex-sys/src/graph_api.rs +24 -1
- data/rust/rubydex-sys/src/name_api.rs +9 -7
- data/rust/rubydex-sys/src/reference_api.rs +37 -0
- metadata +2 -2
|
@@ -424,6 +424,34 @@ pub unsafe extern "C" fn rdx_declaration_members(pointer: GraphPointer, decl_id:
|
|
|
424
424
|
DeclarationsIter::new(declarations.into_boxed_slice())
|
|
425
425
|
}
|
|
426
426
|
|
|
427
|
+
/// Returns the first resolved target declaration for a constant alias declaration, or NULL if the declaration is not
|
|
428
|
+
/// a constant alias or none of its definitions have a resolved target.
|
|
429
|
+
///
|
|
430
|
+
/// # Safety
|
|
431
|
+
///
|
|
432
|
+
/// Assumes that the graph pointer is valid.
|
|
433
|
+
///
|
|
434
|
+
/// # Panics
|
|
435
|
+
///
|
|
436
|
+
/// Will panic if there's inconsistent graph data
|
|
437
|
+
#[unsafe(no_mangle)]
|
|
438
|
+
pub unsafe extern "C" fn rdx_constant_alias_target(pointer: GraphPointer, decl_id: u64) -> *const CDeclaration {
|
|
439
|
+
with_graph(pointer, |graph| {
|
|
440
|
+
let declaration_id = DeclarationId::new(decl_id);
|
|
441
|
+
|
|
442
|
+
let Some(targets) = graph.alias_targets(&declaration_id) else {
|
|
443
|
+
return ptr::null();
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
let Some(&target_id) = targets.first() else {
|
|
447
|
+
return ptr::null();
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
let target_decl = graph.declarations().get(&target_id).unwrap();
|
|
451
|
+
Box::into_raw(Box::new(CDeclaration::from_declaration(target_id, target_decl))).cast_const()
|
|
452
|
+
})
|
|
453
|
+
}
|
|
454
|
+
|
|
427
455
|
/// Creates a new iterator over constant references for a given declaration.
|
|
428
456
|
///
|
|
429
457
|
/// # Safety
|
|
@@ -9,7 +9,7 @@ use libc::{c_char, c_void};
|
|
|
9
9
|
use rubydex::indexing::LanguageId;
|
|
10
10
|
use rubydex::model::encoding::Encoding;
|
|
11
11
|
use rubydex::model::graph::Graph;
|
|
12
|
-
use rubydex::model::ids::{DeclarationId, NameId};
|
|
12
|
+
use rubydex::model::ids::{DeclarationId, NameId, UriId};
|
|
13
13
|
use rubydex::model::keywords;
|
|
14
14
|
use rubydex::model::name::NameRef;
|
|
15
15
|
use rubydex::query::{CompletionCandidate, CompletionContext, CompletionReceiver};
|
|
@@ -260,6 +260,29 @@ pub unsafe extern "C" fn rdx_index_all(
|
|
|
260
260
|
})
|
|
261
261
|
}
|
|
262
262
|
|
|
263
|
+
/// Returns a pointer to the URI ID of the document identified by `uri`, or NULL if it doesn't exist.
|
|
264
|
+
/// Caller must free the returned pointer with `free_u64`.
|
|
265
|
+
///
|
|
266
|
+
/// # Safety
|
|
267
|
+
///
|
|
268
|
+
/// Expects both the graph pointer and uri string pointer to be valid
|
|
269
|
+
#[unsafe(no_mangle)]
|
|
270
|
+
pub unsafe extern "C" fn rdx_graph_get_document(pointer: GraphPointer, uri: *const c_char) -> *const u64 {
|
|
271
|
+
let Ok(uri_str) = (unsafe { utils::convert_char_ptr_to_string(uri) }) else {
|
|
272
|
+
return ptr::null();
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
with_graph(pointer, |graph| {
|
|
276
|
+
let uri_id = UriId::from(uri_str.as_str());
|
|
277
|
+
|
|
278
|
+
if graph.documents().contains_key(&uri_id) {
|
|
279
|
+
Box::into_raw(Box::new(*uri_id)).cast_const()
|
|
280
|
+
} else {
|
|
281
|
+
ptr::null()
|
|
282
|
+
}
|
|
283
|
+
})
|
|
284
|
+
}
|
|
285
|
+
|
|
263
286
|
/// Deletes a document and all of its definitions from the graph.
|
|
264
287
|
/// Returns a pointer to the URI ID if the document was found and removed, or NULL if it didn't exist.
|
|
265
288
|
/// Caller must free the returned pointer with `free_u64`.
|
|
@@ -44,9 +44,10 @@ pub fn nesting_stack_to_name_id(
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
/// Processes a qualified name (e.g., `"Foo::Bar"` or `"<Foo>"`) by splitting on `"::"` and registering each part in the
|
|
47
|
-
/// graph. Singleton class names (starting with `<`) use `ParentScope::Attached` and `nesting
|
|
48
|
-
/// indexer creates them
|
|
49
|
-
/// used as the attachment
|
|
47
|
+
/// graph. Singleton class names (starting with `<`) use `ParentScope::Attached` and a `nesting` equal to the attached
|
|
48
|
+
/// target, matching how the indexer creates them (`class << self` always sits lexically inside its attached class).
|
|
49
|
+
/// When a singleton is the first part (i.e., `current_name` has no parent), `current_nesting` is used as the attachment
|
|
50
|
+
/// point.
|
|
50
51
|
fn process_qualified_name(
|
|
51
52
|
graph: &mut Graph,
|
|
52
53
|
qualified_name: &str,
|
|
@@ -61,12 +62,13 @@ fn process_qualified_name(
|
|
|
61
62
|
}
|
|
62
63
|
|
|
63
64
|
let (parent_scope, nesting_for_part) = if part.starts_with('<') {
|
|
64
|
-
let
|
|
65
|
-
ParentScope::Some(id) | ParentScope::Attached(id) =>
|
|
66
|
-
_ => current_nesting
|
|
65
|
+
let attached_id = match *current_name {
|
|
66
|
+
ParentScope::Some(id) | ParentScope::Attached(id) => Some(id),
|
|
67
|
+
_ => *current_nesting,
|
|
67
68
|
};
|
|
68
69
|
|
|
69
|
-
(
|
|
70
|
+
let attached = attached_id.map_or(ParentScope::None, ParentScope::Attached);
|
|
71
|
+
(attached, attached_id)
|
|
70
72
|
} else {
|
|
71
73
|
(*current_name, *current_nesting)
|
|
72
74
|
};
|
|
@@ -226,6 +226,43 @@ pub unsafe extern "C" fn rdx_resolved_constant_reference_declaration(
|
|
|
226
226
|
})
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
+
/// Returns the declaration of the resolved receiver for the given method reference. Returns NULL when the method
|
|
230
|
+
/// reference has no tracked receiver or when the receiver could not be resolved. Caller must free with
|
|
231
|
+
/// `free_c_declaration`.
|
|
232
|
+
///
|
|
233
|
+
/// # Safety
|
|
234
|
+
///
|
|
235
|
+
/// Assumes pointer is valid.
|
|
236
|
+
///
|
|
237
|
+
/// # Panics
|
|
238
|
+
///
|
|
239
|
+
/// This function will panic if the reference cannot be found.
|
|
240
|
+
#[unsafe(no_mangle)]
|
|
241
|
+
pub unsafe extern "C" fn rdx_method_reference_receiver_declaration(
|
|
242
|
+
pointer: GraphPointer,
|
|
243
|
+
reference_id: u64,
|
|
244
|
+
) -> *const CDeclaration {
|
|
245
|
+
with_graph(pointer, |graph| {
|
|
246
|
+
let ref_id = MethodReferenceId::new(reference_id);
|
|
247
|
+
let reference = graph.method_references().get(&ref_id).expect("Reference not found");
|
|
248
|
+
|
|
249
|
+
let Some(name_id) = reference.receiver() else {
|
|
250
|
+
return ptr::null();
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
let name_ref = graph.names().get(&name_id).expect("Name ID should exist");
|
|
254
|
+
|
|
255
|
+
match name_ref {
|
|
256
|
+
NameRef::Resolved(resolved) => {
|
|
257
|
+
let decl_id = *resolved.declaration_id();
|
|
258
|
+
let decl = graph.declarations().get(&decl_id).expect("Declaration not found");
|
|
259
|
+
Box::into_raw(Box::new(CDeclaration::from_declaration(decl_id, decl))).cast_const()
|
|
260
|
+
}
|
|
261
|
+
NameRef::Unresolved(_) => ptr::null(),
|
|
262
|
+
}
|
|
263
|
+
})
|
|
264
|
+
}
|
|
265
|
+
|
|
229
266
|
/// Returns a newly allocated `Location` for the given method reference id.
|
|
230
267
|
/// Caller must free the returned pointer with `rdx_location_free`.
|
|
231
268
|
///
|
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.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shopify
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-05-01 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
|