rubydex 0.1.0.beta14-aarch64-linux → 0.2.0-aarch64-linux

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cdc01aa399a75ed7879bb08aead637940bcf6311bd73e81e36225bff02911f9e
4
- data.tar.gz: 85d5ffede4745c71b7361576149abc56670ed10a7c3488a218ac82daf10a5c00
3
+ metadata.gz: 44787b43319481966587e2e358c33a55e58800a092864ef132d9c10d2271f5c0
4
+ data.tar.gz: 520ab23713bc163e050622c52b986672e591c116954935e6957c7f8e52dfe343
5
5
  SHA512:
6
- metadata.gz: 17a6b72d3bb15e77b74a19734cd31462c83899fbd96c8a9af81f797a40b6881eafdec3313fc7eb686e8c9cb16c98ef45a4d320aa2063990ba8c0a6f7332b2ba9
7
- data.tar.gz: fbb9acee6525a8a7c94dbca60c26ad11dc507e6e2c540cf655e4e0adb600b81b175392e332a62c93372e2e1264d2bbd8cae8ede0fdd6573b99afa1a3bc5038a9
6
+ metadata.gz: 941b4124e0ec93076390a9a777d538189316512a964d4cc2210ad9775ff14408ccd2912c2e757314304ba4eb343bef241a82399b8a99d8f3b5a9b959608126ff
7
+ data.tar.gz: 74a4eaeeb123b057140cd64529dc4502232ca4b3821a992f6a91cb85994de0b3173f0042249aa8eeab4c53cb7486dde3bb9e7ee3c790dde6d29ad6bbb00b7750
data/exe/rdx CHANGED
@@ -2,11 +2,12 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  $LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
5
+
5
6
  require "optparse"
6
7
 
7
- OptionParser.new do |parser|
8
- parser.banner = "Usage: [path1, path2]"
8
+ options = {}
9
9
 
10
+ OptionParser.new do |parser|
10
11
  parser.on("--version", "Print the gem's version") do
11
12
  require "rubydex/version"
12
13
  puts "v#{Rubydex::VERSION}"
@@ -17,31 +18,34 @@ OptionParser.new do |parser|
17
18
  puts parser
18
19
  exit
19
20
  end
21
+
22
+ parser.on("-i", "--interactive", "Open an interactive session with a populated graph for the current workspace") do
23
+ options[:interactive] = true
24
+ end
20
25
  end.parse!
21
26
 
22
27
  require "rubydex"
23
28
 
24
- workspace_path = ARGV.first
25
-
26
- # If a workspace path is passed, we need to ensure that Bundler is setup in that context so that we find the
27
- # dependencies for that project
28
- if workspace_path
29
- gemfile_path = File.join(workspace_path, "Gemfile")
30
-
31
- if File.exist?(gemfile_path)
32
- ENV["BUNDLE_GEMFILE"] = gemfile_path
33
-
34
- begin
35
- Bundler.setup
36
- rescue Bundler::BundlerError => e
37
- $stderr.puts(<<~MESSAGE)
38
- Bundle setup failed for #{gemfile_path}. Indexing of dependencies may be partial
39
- Error:
40
- #{e.message}
41
- MESSAGE
42
- end
43
- end
29
+ def __with_timer(message, &block)
30
+ print(message)
31
+ start = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond)
32
+ block.call
33
+ duration = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond) - start
34
+ puts " finished in #{duration.round(2)}ms"
44
35
  end
45
36
 
46
- graph = Rubydex::Graph.new(workspace_path: workspace_path)
47
- graph.index_workspace
37
+ graph = Rubydex::Graph.new
38
+ __with_timer("Indexing workspace...") { graph.index_workspace }
39
+ __with_timer("Resolving graph...") { graph.resolve }
40
+
41
+ if options[:interactive]
42
+ begin
43
+ require "irb"
44
+ IRB.setup(nil)
45
+ IRB.conf[:IRB_NAME] = "rubydex"
46
+ workspace = IRB::WorkSpace.new(binding)
47
+ IRB::Irb.new(workspace).run(IRB.conf)
48
+ rescue LoadError
49
+ abort("Interactive mode requires `irb` to be in the bundle")
50
+ end
51
+ end
@@ -141,10 +141,12 @@ end
141
141
 
142
142
  File.write("Makefile", new_makefile)
143
143
 
144
- begin
145
- require "extconf_compile_commands_json"
144
+ if developing_rubydex
145
+ begin
146
+ require "extconf_compile_commands_json"
146
147
 
147
- ExtconfCompileCommandsJson.generate!
148
- ExtconfCompileCommandsJson.symlink!
149
- rescue LoadError # rubocop:disable Lint/SuppressedException
148
+ ExtconfCompileCommandsJson.generate!
149
+ ExtconfCompileCommandsJson.symlink!
150
+ rescue LoadError # rubocop:disable Lint/SuppressedException
151
+ end
150
152
  end
data/ext/rubydex/graph.c CHANGED
@@ -303,6 +303,24 @@ static VALUE rdxr_graph_method_references(VALUE self) {
303
303
  return self;
304
304
  }
305
305
 
306
+ // Graph#document: (String uri) -> Document?
307
+ // Returns the Document for the given URI, or nil if it doesn't exist.
308
+ static VALUE rdxr_graph_document(VALUE self, VALUE uri) {
309
+ Check_Type(uri, T_STRING);
310
+
311
+ void *graph;
312
+ TypedData_Get_Struct(self, void *, &graph_type, graph);
313
+ const uint64_t *uri_id = rdx_graph_get_document(graph, StringValueCStr(uri));
314
+
315
+ if (uri_id == NULL) {
316
+ return Qnil;
317
+ }
318
+
319
+ VALUE argv[] = {self, ULL2NUM(*uri_id)};
320
+ free_u64(uri_id);
321
+ return rb_class_new_instance(2, argv, cDocument);
322
+ }
323
+
306
324
  // Graph#delete_document: (String uri) -> Document?
307
325
  // Deletes a document and all of its definitions from the graph.
308
326
  // Returns the removed Document or nil if it doesn't exist.
@@ -676,6 +694,7 @@ void rdxi_initialize_graph(VALUE moduleRubydex) {
676
694
  rb_define_alloc_func(cGraph, rdxr_graph_alloc);
677
695
  rb_define_method(cGraph, "index_all", rdxr_graph_index_all, 1);
678
696
  rb_define_method(cGraph, "index_source", rdxr_graph_index_source, 3);
697
+ rb_define_method(cGraph, "document", rdxr_graph_document, 1);
679
698
  rb_define_method(cGraph, "delete_document", rdxr_graph_delete_document, 1);
680
699
  rb_define_method(cGraph, "resolve", rdxr_graph_resolve, 0);
681
700
  rb_define_method(cGraph, "resolve_constant", rdxr_graph_resolve_constant, 2);
@@ -75,6 +75,28 @@ static VALUE rdxr_method_reference_location(VALUE self) {
75
75
  return location;
76
76
  }
77
77
 
78
+ // MethodReference#receiver -> Rubydex::Declaration?
79
+ // Returns the resolved declaration for the receiver of the method call. Returns nil when the receiver is not a
80
+ // tracked constant or cannot be resolved.
81
+ static VALUE rdxr_method_reference_receiver(VALUE self) {
82
+ HandleData *data;
83
+ TypedData_Get_Struct(self, HandleData, &handle_type, data);
84
+
85
+ void *graph;
86
+ TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
87
+
88
+ const struct CDeclaration *decl = rdx_method_reference_receiver_declaration(graph, data->id);
89
+ if (decl == NULL) {
90
+ return Qnil;
91
+ }
92
+
93
+ VALUE decl_class = rdxi_declaration_class_for_kind(decl->kind);
94
+ VALUE argv[] = {data->graph_obj, ULL2NUM(decl->id)};
95
+ free_c_declaration(decl);
96
+
97
+ return rb_class_new_instance(2, argv, decl_class);
98
+ }
99
+
78
100
  // ResolvedConstantReference#declaration -> Declaration
79
101
  static VALUE rdxr_resolved_constant_reference_declaration(VALUE self) {
80
102
  HandleData *data;
@@ -120,4 +142,5 @@ void rdxi_initialize_reference(VALUE mRubydex) {
120
142
  rb_define_method(cMethodReference, "initialize", rdxr_handle_initialize, 2);
121
143
  rb_define_method(cMethodReference, "name", rdxr_method_reference_name, 0);
122
144
  rb_define_method(cMethodReference, "location", rdxr_method_reference_location, 0);
145
+ rb_define_method(cMethodReference, "receiver", rdxr_method_reference_receiver, 0);
123
146
  }
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rubydex
4
- VERSION = "0.1.0.beta14"
4
+ VERSION = "0.2.0"
5
5
  end
data/rbi/rubydex.rbi CHANGED
@@ -259,6 +259,9 @@ class Rubydex::Graph
259
259
  sig { params(uri: String).returns(T.nilable(Rubydex::Document)) }
260
260
  def delete_document(uri); end
261
261
 
262
+ sig { params(uri: String).returns(T.nilable(Rubydex::Document)) }
263
+ def document(uri); end
264
+
262
265
  sig { returns(T::Array[Rubydex::Diagnostic]) }
263
266
  def diagnostics; end
264
267
 
@@ -415,6 +418,9 @@ class Rubydex::MethodReference < Rubydex::Reference
415
418
 
416
419
  sig { returns(String) }
417
420
  def name; end
421
+
422
+ sig { returns(T.nilable(Rubydex::Declaration)) }
423
+ def receiver; end
418
424
  end
419
425
 
420
426
  class Rubydex::Reference
@@ -234,6 +234,7 @@ impl<'a> RubyIndexer<'a> {
234
234
  Offset::from_prism_location(&name_loc),
235
235
  str_id,
236
236
  )));
237
+ self.visit(&opt_param.value());
237
238
  }
238
239
 
239
240
  if let Some(rest) = parameters_list.rest() {
@@ -276,6 +277,7 @@ impl<'a> RubyIndexer<'a> {
276
277
  let str_id = self.local_graph.intern_string(self.offset_to_string(&offset));
277
278
 
278
279
  parameters.push(Parameter::OptionalKeyword(ParameterStruct::new(offset, str_id)));
280
+ self.visit(&optional.value());
279
281
  }
280
282
  _ => {}
281
283
  }
@@ -4060,6 +4060,19 @@ mod constant_reference_tests {
4060
4060
  );
4061
4061
  }
4062
4062
 
4063
+ #[test]
4064
+ fn index_unresolved_constant_references_in_default_values() {
4065
+ let context = index_source({
4066
+ "
4067
+ def foo(a = C1, b = C2::C3); end
4068
+ def bar(a: C4, b: C5::C6); end
4069
+ "
4070
+ });
4071
+
4072
+ assert_no_local_diagnostics!(&context);
4073
+ assert_constant_references_eq!(&context, ["C1", "C2", "C3", "C4", "C5", "C6"]);
4074
+ }
4075
+
4063
4076
  #[test]
4064
4077
  fn index_constant_path_and_write_visits_value() {
4065
4078
  let context = index_source({
@@ -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`.
@@ -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.1.0.beta14
4
+ version: 0.2.0
5
5
  platform: aarch64-linux
6
6
  authors:
7
7
  - Shopify
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-04-28 00:00:00.000000000 Z
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