Skip to content

Commit 4e80bcc

Browse files
authored
Merge pull request #870 from Shopify/ar-location-from-prism
Add `Location.from_prism` helper
2 parents ab88ef1 + 4ad85bd commit 4e80bcc

3 files changed

Lines changed: 61 additions & 0 deletions

File tree

lib/rubydex/location.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@ class NotFileUriError < StandardError; end
1414
#: Integer
1515
attr_reader :start_line, :end_line, :start_column, :end_column
1616

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+
1730
#: (?uri: String, ?start_line: Integer, ?end_line: Integer, ?start_column: Integer, ?end_column: Integer) -> void
1831
def initialize(uri:, start_line:, end_line:, start_column:, end_column:)
1932
@uri = uri
@@ -68,6 +81,17 @@ def to_s
6881
# A one based location intended for display purposes. This is what should be used when displaying a location to users,
6982
# like in CLIs
7083
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+
7195
# Returns itself
7296
#
7397
#: () -> DisplayLocation

rbi/rubydex.rbi

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,11 @@ class Rubydex::Graph
415415
end
416416

417417
class Rubydex::DisplayLocation < Rubydex::Location
418+
class << self
419+
sig { params(prism_location: Prism::Location, uri: String).returns(T.noreturn) }
420+
def from_prism(prism_location, uri:); end
421+
end
422+
418423
sig { returns([String, Integer, Integer, Integer, Integer]) }
419424
def comparable_values; end
420425

@@ -428,6 +433,11 @@ end
428433
class Rubydex::Location
429434
include ::Comparable
430435

436+
class << self
437+
sig { params(prism_location: Prism::Location, uri: String).returns(Rubydex::Location) }
438+
def from_prism(prism_location, uri:); end
439+
end
440+
431441
sig do
432442
params(
433443
uri: String,

test/location_test.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,33 @@
33
require "test_helper"
44

55
class LocationTest < Minitest::Test
6+
PrismLocation = Struct.new(:start_line, :start_column, :end_line, :end_column, keyword_init: true)
7+
8+
def test_location_from_prism
9+
prism_location = PrismLocation.new(start_line: 2, start_column: 12, end_line: 3, end_column: 19)
10+
11+
location = Rubydex::Location.from_prism(prism_location, uri: "file:///foo.rb")
12+
13+
assert_equal(
14+
Rubydex::Location.new(uri: "file:///foo.rb", start_line: 1, end_line: 2, start_column: 12, end_column: 19),
15+
location,
16+
)
17+
end
18+
19+
def test_display_location_from_prism_raises_with_conversion_path
20+
prism_location = PrismLocation.new(start_line: 2, start_column: 12, end_line: 3, end_column: 19)
21+
22+
error = assert_raises(NotImplementedError) do
23+
Rubydex::DisplayLocation.from_prism(prism_location, uri: "file:///foo.rb")
24+
end
25+
26+
assert_equal(<<~MESSAGE, error.message)
27+
Cannot convert Prism::Location directly to a Rubydex::DisplayLocation.
28+
Start with `Rubydex::Location.from_prism(...)` and then convert the resulting
29+
location with `to_display`
30+
MESSAGE
31+
end
32+
633
def test_location_equality
734
a = Rubydex::Location.new(uri: "file:///foo.rb", start_line: 0, end_line: 0, start_column: 0, end_column: 5)
835
b = Rubydex::Location.new(uri: "file:///foo.rb", start_line: 0, end_line: 0, start_column: 0, end_column: 5)

0 commit comments

Comments
 (0)