rubydex 0.2.5 → 0.2.7

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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -16
  3. data/THIRD_PARTY_LICENSES.html +45 -12
  4. data/exe/rdx +2 -0
  5. data/ext/rubydex/declaration.c +115 -106
  6. data/ext/rubydex/definition.c +123 -72
  7. data/ext/rubydex/diagnostic.c +5 -0
  8. data/ext/rubydex/document.c +51 -23
  9. data/ext/rubydex/extconf.rb +1 -1
  10. data/ext/rubydex/graph.c +253 -66
  11. data/ext/rubydex/handle.h +34 -5
  12. data/ext/rubydex/location.c +5 -0
  13. data/ext/rubydex/reference.c +51 -46
  14. data/ext/rubydex/rubydex.c +5 -0
  15. data/ext/rubydex/signature.c +5 -0
  16. data/ext/rubydex/utils.c +13 -0
  17. data/ext/rubydex/utils.h +4 -0
  18. data/lib/rubydex/bin/rubydex_mcp.exe +0 -0
  19. data/lib/rubydex/errors.rb +11 -0
  20. data/lib/rubydex/graph.rb +9 -28
  21. data/lib/rubydex/location.rb +24 -0
  22. data/lib/rubydex/version.rb +1 -1
  23. data/lib/rubydex.rb +1 -0
  24. data/rbi/rubydex.rbi +40 -15
  25. data/rust/Cargo.lock +122 -17
  26. data/rust/rubydex/Cargo.toml +26 -2
  27. data/rust/rubydex/benches/graph_memory.rs +46 -0
  28. data/rust/rubydex/src/config.rs +275 -0
  29. data/rust/rubydex/src/dot.rs +609 -0
  30. data/rust/rubydex/src/errors.rs +2 -0
  31. data/rust/rubydex/src/indexing/rbs_indexer.rs +19 -1
  32. data/rust/rubydex/src/indexing/ruby_indexer.rs +4 -0
  33. data/rust/rubydex/src/lib.rs +8 -1
  34. data/rust/rubydex/src/main.rs +8 -5
  35. data/rust/rubydex/src/model/built_in.rs +5 -2
  36. data/rust/rubydex/src/model/comment.rs +2 -0
  37. data/rust/rubydex/src/model/declaration.rs +13 -51
  38. data/rust/rubydex/src/model/definitions.rs +13 -1
  39. data/rust/rubydex/src/model/document.rs +2 -0
  40. data/rust/rubydex/src/model/encoding.rs +2 -0
  41. data/rust/rubydex/src/model/graph.rs +88 -27
  42. data/rust/rubydex/src/model/identity_maps.rs +3 -0
  43. data/rust/rubydex/src/model/keywords.rs +3 -0
  44. data/rust/rubydex/src/model/name.rs +2 -0
  45. data/rust/rubydex/src/model/string_ref.rs +2 -0
  46. data/rust/rubydex/src/model/visibility.rs +3 -0
  47. data/rust/rubydex/src/operation/applier.rs +1 -0
  48. data/rust/rubydex/src/operation/mod.rs +1 -0
  49. data/rust/rubydex/src/operation/ruby_builder.rs +4 -0
  50. data/rust/rubydex/src/query.rs +114 -33
  51. data/rust/rubydex/src/resolution.rs +18 -20
  52. data/rust/rubydex/src/resolution_tests.rs +132 -0
  53. data/rust/rubydex/tests/cli.rs +17 -61
  54. data/rust/rubydex-mcp/Cargo.toml +9 -3
  55. data/rust/rubydex-sys/Cargo.toml +9 -2
  56. data/rust/rubydex-sys/src/definition_api.rs +72 -2
  57. data/rust/rubydex-sys/src/document_api.rs +28 -0
  58. data/rust/rubydex-sys/src/graph_api.rs +74 -6
  59. metadata +6 -4
  60. data/rust/rubydex/src/visualization/dot.rs +0 -192
  61. data/rust/rubydex/src/visualization.rs +0 -6
@@ -4,6 +4,12 @@
4
4
  #include "handle.h"
5
5
  #include "location.h"
6
6
  #include "rustbindings.h"
7
+ #include "utils.h"
8
+
9
+ /*
10
+ * RDoc parser workaround for https://github.com/ruby/rdoc/issues/1744:
11
+ * mRubydex = rb_define_module("Rubydex")
12
+ */
7
13
 
8
14
  VALUE cReference;
9
15
  VALUE cConstantReference;
@@ -11,31 +17,29 @@ VALUE cUnresolvedConstantReference;
11
17
  VALUE cResolvedConstantReference;
12
18
  VALUE cMethodReference;
13
19
 
14
- // ConstantReference#name -> String
20
+ /*
21
+ * call-seq:
22
+ * name -> String
23
+ *
24
+ * Returns the unresolved constant name.
25
+ */
15
26
  static VALUE rdxr_constant_reference_name(VALUE self) {
16
27
  HandleData *data;
17
- TypedData_Get_Struct(self, HandleData, &handle_type, data);
18
-
19
- void *graph;
20
- TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
28
+ void *graph = rdxi_graph_from_handle(self, &data);
21
29
 
22
30
  const char *name = rdx_constant_reference_name(graph, data->id);
23
- if (name == NULL) {
24
- return Qnil;
25
- }
26
-
27
- VALUE str = rb_utf8_str_new_cstr(name);
28
- free_c_string(name);
29
- return str;
31
+ return rdxi_owned_c_string_to_ruby(name);
30
32
  }
31
33
 
32
- // ConstantReference#location -> Rubydex::Location
34
+ /*
35
+ * call-seq:
36
+ * location -> Rubydex::Location
37
+ *
38
+ * Returns the source location for this constant reference.
39
+ */
33
40
  static VALUE rdxr_constant_reference_location(VALUE self) {
34
41
  HandleData *data;
35
- TypedData_Get_Struct(self, HandleData, &handle_type, data);
36
-
37
- void *graph;
38
- TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
42
+ void *graph = rdxi_graph_from_handle(self, &data);
39
43
 
40
44
  Location *loc = rdx_constant_reference_location(graph, data->id);
41
45
  VALUE location = rdxi_build_location_value(loc);
@@ -43,31 +47,29 @@ static VALUE rdxr_constant_reference_location(VALUE self) {
43
47
  return location;
44
48
  }
45
49
 
46
- // MethodReference#name -> String
50
+ /*
51
+ * call-seq:
52
+ * name -> String
53
+ *
54
+ * Returns the referenced method name.
55
+ */
47
56
  static VALUE rdxr_method_reference_name(VALUE self) {
48
57
  HandleData *data;
49
- TypedData_Get_Struct(self, HandleData, &handle_type, data);
50
-
51
- void *graph;
52
- TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
58
+ void *graph = rdxi_graph_from_handle(self, &data);
53
59
 
54
60
  const char *name = rdx_method_reference_name(graph, data->id);
55
- if (name == NULL) {
56
- return Qnil;
57
- }
58
-
59
- VALUE str = rb_utf8_str_new_cstr(name);
60
- free_c_string(name);
61
- return str;
61
+ return rdxi_owned_c_string_to_ruby(name);
62
62
  }
63
63
 
64
- // MethodReference#location -> Rubydex::Location
64
+ /*
65
+ * call-seq:
66
+ * location -> Rubydex::Location
67
+ *
68
+ * Returns the source location for this method reference.
69
+ */
65
70
  static VALUE rdxr_method_reference_location(VALUE self) {
66
71
  HandleData *data;
67
- TypedData_Get_Struct(self, HandleData, &handle_type, data);
68
-
69
- void *graph;
70
- TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
72
+ void *graph = rdxi_graph_from_handle(self, &data);
71
73
 
72
74
  Location *loc = rdx_method_reference_location(graph, data->id);
73
75
  VALUE location = rdxi_build_location_value(loc);
@@ -75,15 +77,16 @@ static VALUE rdxr_method_reference_location(VALUE self) {
75
77
  return location;
76
78
  }
77
79
 
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.
80
+ /*
81
+ * call-seq:
82
+ * receiver -> Rubydex::Declaration?
83
+ *
84
+ * Returns the resolved declaration for the receiver of the method call. Returns nil when the receiver is not a tracked
85
+ * constant or cannot be resolved.
86
+ */
81
87
  static VALUE rdxr_method_reference_receiver(VALUE self) {
82
88
  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);
89
+ void *graph = rdxi_graph_from_handle(self, &data);
87
90
 
88
91
  const struct CDeclaration *decl = rdx_method_reference_receiver_declaration(graph, data->id);
89
92
  if (decl == NULL) {
@@ -97,13 +100,15 @@ static VALUE rdxr_method_reference_receiver(VALUE self) {
97
100
  return rb_class_new_instance(2, argv, decl_class);
98
101
  }
99
102
 
100
- // ResolvedConstantReference#declaration -> Declaration
103
+ /*
104
+ * call-seq:
105
+ * declaration -> Rubydex::Declaration
106
+ *
107
+ * Returns the resolved declaration.
108
+ */
101
109
  static VALUE rdxr_resolved_constant_reference_declaration(VALUE self) {
102
110
  HandleData *data;
103
- TypedData_Get_Struct(self, HandleData, &handle_type, data);
104
-
105
- void *graph;
106
- TypedData_Get_Struct(data->graph_obj, void *, &graph_type, graph);
111
+ void *graph = rdxi_graph_from_handle(self, &data);
107
112
 
108
113
  const struct CDeclaration *decl = rdx_resolved_constant_reference_declaration(graph, data->id);
109
114
  if (decl == NULL) {
@@ -12,6 +12,11 @@ VALUE mRubydex;
12
12
  void Init_rubydex(void) {
13
13
  rb_ext_ractor_safe(true);
14
14
 
15
+ /*
16
+ * Document-module: Rubydex
17
+ *
18
+ * Namespace for Rubydex's Ruby API.
19
+ */
15
20
  mRubydex = rb_define_module("Rubydex");
16
21
  rdxi_initialize_graph(mRubydex);
17
22
  rdxi_initialize_declaration(mRubydex);
@@ -1,6 +1,11 @@
1
1
  #include "signature.h"
2
2
  #include "location.h"
3
3
 
4
+ /*
5
+ * RDoc parser workaround for https://github.com/ruby/rdoc/issues/1744:
6
+ * mRubydex = rb_define_module("Rubydex")
7
+ */
8
+
4
9
  static VALUE empty_params = Qundef;
5
10
 
6
11
  VALUE cSignature;
data/ext/rubydex/utils.c CHANGED
@@ -39,6 +39,19 @@ void rdxi_check_array_of_strings(VALUE array) {
39
39
  }
40
40
  }
41
41
 
42
+ // Convert a Rust-owned C string to a Ruby string and release it with free_c_string.
43
+ // Returns nil when the Rust side returned NULL.
44
+ VALUE rdxi_owned_c_string_to_ruby(const char *string) {
45
+ if (string == NULL) {
46
+ return Qnil;
47
+ }
48
+
49
+ VALUE value = rb_utf8_str_new_cstr(string);
50
+ free_c_string(string);
51
+
52
+ return value;
53
+ }
54
+
42
55
  // Yield body for iterating over declarations
43
56
  VALUE rdxi_declarations_yield(VALUE args) {
44
57
  VALUE self = rb_ary_entry(args, 0);
data/ext/rubydex/utils.h CHANGED
@@ -13,6 +13,10 @@ void rdxi_free_str_array(char **array, size_t length);
13
13
  // Verify that the Ruby object is an array of strings or raise `TypeError`
14
14
  void rdxi_check_array_of_strings(VALUE array);
15
15
 
16
+ // Convert a Rust-owned C string to a Ruby string and release it with free_c_string.
17
+ // Returns nil when the Rust side returned NULL.
18
+ VALUE rdxi_owned_c_string_to_ruby(const char *string);
19
+
16
20
  // Yield body for iterating over declarations
17
21
  VALUE rdxi_declarations_yield(VALUE args);
18
22
 
Binary file
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rubydex
4
+ class Error < StandardError; end
5
+
6
+ # Raised when `MethodAliasDefinition#target` walks an alias chain that loops back on itself.
7
+ class AliasCycleError < Error; end
8
+
9
+ # Raised by `Graph#load_config` when the requested config file does not exist, cannot be read, or is malformed
10
+ class ConfigError < Error; end
11
+ end
data/lib/rubydex/graph.rb CHANGED
@@ -5,49 +5,30 @@ module Rubydex
5
5
  #
6
6
  # Note: this class is partially defined in C to integrate with the Rust backend
7
7
  class Graph
8
- IGNORED_DIRECTORIES = [
9
- ".bundle",
10
- ".claude",
11
- ".git",
12
- ".github",
13
- ".ruby-lsp",
14
- ".vscode",
15
- "log",
16
- "node_modules",
17
- "tmp",
18
- ].freeze
19
-
20
8
  INDEXABLE_EXTENSIONS = [".rb", ".rake", ".rbs", ".ru"].freeze
21
9
 
22
- #: String
23
- attr_accessor :workspace_path
24
-
25
- #: (?workspace_path: String) -> void
26
- def initialize(workspace_path: Dir.pwd)
27
- @workspace_path = workspace_path
28
-
29
- exclude_paths(IGNORED_DIRECTORIES.map { |dir| File.join(@workspace_path, dir) })
10
+ #: (?workspace_path: String?) -> void
11
+ def initialize(workspace_path: nil)
12
+ self.workspace_path = workspace_path if workspace_path
30
13
  end
31
14
 
32
- # Index all files and dependencies of the workspace that exists in `@workspace_path`
15
+ # Index all files and dependencies of the workspace that exists in `workspace_path`
33
16
  #: -> Array[String]
34
17
  def index_workspace
35
18
  index_all(workspace_paths)
36
19
  end
37
20
 
38
- # Returns all workspace paths that should be indexed, excluding directories that we don't need to descend into such
39
- # as `.git`, `node_modules`. Also includes any top level Ruby files
21
+ # Returns all workspace paths that should be indexed
40
22
  #
41
23
  #: -> Array[String]
42
24
  def workspace_paths
43
25
  paths = []
26
+ root = workspace_path
44
27
 
45
- Dir.each_child(@workspace_path) do |entry|
46
- full_path = File.join(@workspace_path, entry)
28
+ Dir.each_child(root) do |entry|
29
+ full_path = File.join(root, entry)
47
30
 
48
- if File.directory?(full_path)
49
- paths << full_path unless IGNORED_DIRECTORIES.include?(entry)
50
- elsif INDEXABLE_EXTENSIONS.include?(File.extname(entry))
31
+ if File.directory?(full_path) || INDEXABLE_EXTENSIONS.include?(File.extname(entry))
51
32
  paths << full_path
52
33
  end
53
34
  end
@@ -14,6 +14,19 @@ module Rubydex
14
14
  #: Integer
15
15
  attr_reader :start_line, :end_line, :start_column, :end_column
16
16
 
17
+ class << self
18
+ #: (Prism::Location prism_location, uri: String) -> Location
19
+ def from_prism(prism_location, uri:)
20
+ Location.new(
21
+ uri: uri,
22
+ start_line: prism_location.start_line - 1,
23
+ start_column: prism_location.start_column,
24
+ end_line: prism_location.end_line - 1,
25
+ end_column: prism_location.end_column,
26
+ )
27
+ end
28
+ end
29
+
17
30
  #: (?uri: String, ?start_line: Integer, ?end_line: Integer, ?start_column: Integer, ?end_column: Integer) -> void
18
31
  def initialize(uri:, start_line:, end_line:, start_column:, end_column:)
19
32
  @uri = uri
@@ -68,6 +81,17 @@ module Rubydex
68
81
  # A one based location intended for display purposes. This is what should be used when displaying a location to users,
69
82
  # like in CLIs
70
83
  class DisplayLocation < Location
84
+ class << self
85
+ #: (Prism::Location prism_location, uri: String) -> Location
86
+ def from_prism(prism_location, uri:)
87
+ raise NotImplementedError, <<~MESSAGE
88
+ Cannot convert Prism::Location directly to a Rubydex::DisplayLocation.
89
+ Start with `Rubydex::Location.from_prism(...)` and then convert the resulting
90
+ location with `to_display`
91
+ MESSAGE
92
+ end
93
+ end
94
+
71
95
  # Returns itself
72
96
  #
73
97
  #: () -> DisplayLocation
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rubydex
4
- VERSION = "0.2.5"
4
+ VERSION = "0.2.7"
5
5
  end
data/lib/rubydex.rb CHANGED
@@ -14,6 +14,7 @@ rescue LoadError
14
14
  require "rubydex/rubydex"
15
15
  end
16
16
 
17
+ require "rubydex/errors"
17
18
  require "rubydex/failures"
18
19
  require "rubydex/location"
19
20
  require "rubydex/comment"
data/rbi/rubydex.rbi CHANGED
@@ -174,7 +174,12 @@ class Rubydex::ConstantDefinition < Rubydex::Definition; end
174
174
  class Rubydex::GlobalVariableAliasDefinition < Rubydex::Definition; end
175
175
  class Rubydex::GlobalVariableDefinition < Rubydex::Definition; end
176
176
  class Rubydex::InstanceVariableDefinition < Rubydex::Definition; end
177
- class Rubydex::MethodAliasDefinition < Rubydex::Definition; end
177
+
178
+ class Rubydex::MethodAliasDefinition < Rubydex::Definition
179
+ sig { returns(T.nilable(Rubydex::Method)) }
180
+ def target; end
181
+ end
182
+
178
183
  class Rubydex::MethodDefinition < Rubydex::Definition; end
179
184
 
180
185
  class Rubydex::ModuleDefinition < Rubydex::Definition
@@ -246,6 +251,9 @@ class Rubydex::Document
246
251
  sig { returns(T::Enumerable[Rubydex::Definition]) }
247
252
  def definitions; end
248
253
 
254
+ sig { returns(T::Enumerable[Rubydex::MethodReference]) }
255
+ def method_references; end
256
+
249
257
  sig { returns(String) }
250
258
  def uri; end
251
259
 
@@ -257,6 +265,8 @@ class Rubydex::Document
257
265
  end
258
266
 
259
267
  class Rubydex::Error < StandardError; end
268
+ class Rubydex::AliasCycleError < Rubydex::Error; end
269
+ class Rubydex::ConfigError < Rubydex::Error; end
260
270
 
261
271
  class Rubydex::Failure
262
272
  sig { params(message: String).void }
@@ -269,8 +279,6 @@ end
269
279
  class Rubydex::IntegrityFailure < Rubydex::Failure; end
270
280
 
271
281
  class Rubydex::Graph
272
- IGNORED_DIRECTORIES = T.let(T.unsafe(nil), T::Array[String])
273
-
274
282
  sig { params(workspace_path: T.nilable(String)).void }
275
283
  def initialize(workspace_path: nil); end
276
284
 
@@ -301,10 +309,17 @@ class Rubydex::Graph
301
309
  sig { params(uri: String, source: String, language_id: String).void }
302
310
  def index_source(uri, source, language_id); end
303
311
 
304
- # Index all files and dependencies of the workspace that exists in `@workspace_path`
312
+ # Index all files and dependencies of the workspace that exists in `workspace_path`
305
313
  sig { returns(T::Array[String]) }
306
314
  def index_workspace; end
307
315
 
316
+ # Loads configuration, merging its excluded paths into the graph's configuration (the workspace path is never
317
+ # overridden). With `config_path` (resolved relative to the workspace path), an explicitly named file that does not
318
+ # exist raises `Rubydex::ConfigError`. With no argument, the default `.rubydex` is loaded if present and ignored if
319
+ # missing. Raises `Rubydex::ConfigError` if a file cannot be read or is malformed.
320
+ sig { params(config_path: T.nilable(String)).void }
321
+ def load_config(config_path = nil); end
322
+
308
323
  sig { returns(T::Enumerable[Rubydex::MethodReference]) }
309
324
  def method_references; end
310
325
 
@@ -344,48 +359,48 @@ class Rubydex::Graph
344
359
  # Returns completion candidates for an expression context. This includes all keywords, constants, methods, instance
345
360
  # variables, class variables and global variables reachable from the current lexical scope and self type.
346
361
  #
347
- # The nesting array represents the lexical scope stack. The optional `self_receiver` keyword argument overrides the
362
+ # The nesting array represents the lexical scope stack. The required `self_receiver` keyword argument overrides the
348
363
  # self type independently of the lexical scope (e.g., `"Foo::<Foo>"` for `def Foo.bar`). This distinction is important
349
364
  # because constants and class variables are always attached to the lexical scope. Meanwhile, methods and instance
350
- # variables are attached to the type of `self` and those don't always match.
365
+ # variables are attached to the type of `self` and those don't always match. Pass `nil` when the self type is unknown
351
366
  sig do
352
367
  params(
353
368
  nesting: T::Array[String],
354
369
  self_receiver: T.nilable(String),
355
370
  ).returns(T::Array[T.any(Rubydex::Declaration, Rubydex::Keyword)])
356
371
  end
357
- def complete_expression(nesting, self_receiver: nil); end
372
+ def complete_expression(nesting, self_receiver:); end
358
373
 
359
374
  # Returns completion candidates after a namespace access operator (e.g., `Foo::`). This includes all constants and
360
375
  # singleton methods for the namespace and its ancestors.
361
376
  #
362
- # The optional `self_receiver` kwarg is the caller's runtime self type. It's used to filter visibility-restricted
363
- # singleton methods (e.g., `private_class_method`). Pass `nil` (the default) for top-level/script scope.
377
+ # The required `self_receiver` kwarg is the caller's runtime self type. It's used to filter visibility-restricted
378
+ # singleton methods (e.g., `private_class_method`). Pass `nil` for top-level/script scope.
364
379
  sig do
365
380
  params(
366
381
  name: String,
367
382
  self_receiver: T.nilable(String),
368
383
  ).returns(T::Array[Rubydex::Declaration])
369
384
  end
370
- def complete_namespace_access(name, self_receiver: nil); end
385
+ def complete_namespace_access(name, self_receiver:); end
371
386
 
372
387
  # Returns completion candidates after a method call operator (e.g., `foo.`). This includes all methods that exist on
373
388
  # the type of the receiver and its ancestors.
374
389
  #
375
- # The optional `self_receiver` kwarg is the caller's runtime self type. It's used for visibility checks for `private`
376
- # and `protected` methods. Pass `nil` (the default) for top-level/script scope.
390
+ # The required `self_receiver` kwarg is the caller's runtime self type. It's used for visibility checks for `private`
391
+ # and `protected` methods. Pass `nil` for top-level/script scope.
377
392
  sig do
378
393
  params(
379
394
  name: String,
380
395
  self_receiver: T.nilable(String),
381
396
  ).returns(T::Array[Rubydex::Method])
382
397
  end
383
- def complete_method_call(name, self_receiver: nil); end
398
+ def complete_method_call(name, self_receiver:); end
384
399
 
385
400
  # Returns completion candidates inside a method call's argument list (e.g., `foo.bar(|)`). This includes everything
386
401
  # that expression completion provides plus keyword argument names of the method being called.
387
402
  #
388
- # See `complete_expression` for the semantics of `nesting` and `self_receiver`.
403
+ # See `complete_expression` for the semantics of `nesting` and `self_receiver` (required, may be `nil`).
389
404
  sig do
390
405
  params(
391
406
  name: String,
@@ -393,7 +408,7 @@ class Rubydex::Graph
393
408
  self_receiver: T.nilable(String),
394
409
  ).returns(T::Array[T.any(Rubydex::Declaration, Rubydex::Keyword, Rubydex::KeywordParameter)])
395
410
  end
396
- def complete_method_argument(name, nesting, self_receiver: nil); end
411
+ def complete_method_argument(name, nesting, self_receiver:); end
397
412
 
398
413
  private
399
414
 
@@ -411,6 +426,11 @@ class Rubydex::Graph
411
426
  end
412
427
 
413
428
  class Rubydex::DisplayLocation < Rubydex::Location
429
+ class << self
430
+ sig { params(prism_location: Prism::Location, uri: String).returns(T.noreturn) }
431
+ def from_prism(prism_location, uri:); end
432
+ end
433
+
414
434
  sig { returns([String, Integer, Integer, Integer, Integer]) }
415
435
  def comparable_values; end
416
436
 
@@ -424,6 +444,11 @@ end
424
444
  class Rubydex::Location
425
445
  include ::Comparable
426
446
 
447
+ class << self
448
+ sig { params(prism_location: Prism::Location, uri: String).returns(Rubydex::Location) }
449
+ def from_prism(prism_location, uri:); end
450
+ end
451
+
427
452
  sig do
428
453
  params(
429
454
  uri: String,