summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2024-02-13 14:58:41 -0500
committergit <svn-admin@ruby-lang.org>2024-02-13 20:10:25 +0000
commitb1964a92044f97f3b71ec98906c02083e28a7226 (patch)
treede7832f5ffa9c2d6da9eb54c19dd4a639bb264b9 /lib
parent6261d4b4d8112a461ac5a383032490007f47029c (diff)
[ruby/prism] Add code unit APIs to location
LSPs need this because the protocol dictates that you return code units for offsets. None of our existing APIs provided that information, and since we hid the source it's not nearly as useful for them. Now they can pass an encoding directly to: * Location#start_code_units_offset * Location#end_code_units_offset * Location#start_code_units_column * Location#end_code_units_column https://github.com/ruby/prism/commit/4757a2cc06 Co-Authored-By: Vinicius Stock <vinicius.stock@shopify.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/prism/parse_result.rb39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/prism/parse_result.rb b/lib/prism/parse_result.rb
index a27f30d43b..4b0c57ed4b 100644
--- a/lib/prism/parse_result.rb
+++ b/lib/prism/parse_result.rb
@@ -56,6 +56,23 @@ module Prism
character_offset(byte_offset) - character_offset(line_start(byte_offset))
end
+ # Returns the offset from the start of the file for the given byte offset
+ # counting in code units for the given encoding.
+ #
+ # This method is tested with UTF-8, UTF-16, and UTF-32. If there is the
+ # concept of code units that differs from the number of characters in other
+ # encodings, it is not captured here.
+ def code_units_offset(byte_offset, encoding)
+ byteslice = source.byteslice(0, byte_offset).encode(encoding)
+ (encoding == Encoding::UTF_16LE || encoding == Encoding::UTF_16BE) ? (byteslice.bytesize / 2) : byteslice.length
+ end
+
+ # Returns the column number in code units for the given encoding for the
+ # given byte offset.
+ def code_units_column(byte_offset, encoding)
+ code_units_offset(byte_offset, encoding) - code_units_offset(line_start(byte_offset), encoding)
+ end
+
private
# Binary search through the offsets to find the line number for the given
@@ -138,6 +155,11 @@ module Prism
source.character_offset(start_offset)
end
+ # The offset from the start of the file in code units of the given encoding.
+ def start_code_units_offset(encoding = Encoding::UTF_16LE)
+ source.code_units_offset(start_offset, encoding)
+ end
+
# The byte offset from the beginning of the source where this location ends.
def end_offset
start_offset + length
@@ -149,6 +171,11 @@ module Prism
source.character_offset(end_offset)
end
+ # The offset from the start of the file in code units of the given encoding.
+ def end_code_units_offset(encoding = Encoding::UTF_16LE)
+ source.code_units_offset(end_offset, encoding)
+ end
+
# The line number where this location starts.
def start_line
source.line(start_offset)
@@ -177,6 +204,12 @@ module Prism
source.character_column(start_offset)
end
+ # The column number in code units of the given encoding where this location
+ # starts from the start of the line.
+ def start_code_units_column(encoding = Encoding::UTF_16LE)
+ source.code_units_column(start_offset, encoding)
+ end
+
# The column number in bytes where this location ends from the start of the
# line.
def end_column
@@ -189,6 +222,12 @@ module Prism
source.character_column(end_offset)
end
+ # The column number in code units of the given encoding where this location
+ # ends from the start of the line.
+ def end_code_units_column(encoding = Encoding::UTF_16LE)
+ source.code_units_column(end_offset, encoding)
+ end
+
# Implement the hash pattern matching interface for Location.
def deconstruct_keys(keys)
{ start_offset: start_offset, end_offset: end_offset }