class Prism::CodeUnitsCache

A cache that can be used to quickly compute code unit offsets from byte offsets. It purposefully provides only a single [] method to access the cache in order to minimize surface area.

Note that there are some known issues here that may or may not be addressed in the future:

Public Class Methods

new(source, encoding) click to toggle source

Initialize a new cache with the given source and encoding.

# File lib/prism/parse_result.rb, line 212
def initialize(source, encoding)
  @source = source
  @counter =
    if encoding == Encoding::UTF_16LE || encoding == Encoding::UTF_16BE
      UTF16Counter.new(source, encoding)
    else
      LengthCounter.new(source, encoding)
    end

  @cache = {} #: Hash[Integer, Integer]
  @offsets = [] #: Array[Integer]
end

Public Instance Methods

[](byte_offset) click to toggle source

Retrieve the code units offset from the given byte offset.

# File lib/prism/parse_result.rb, line 226
def [](byte_offset)
  @cache[byte_offset] ||=
    if (index = @offsets.bsearch_index { |offset| offset > byte_offset }).nil?
      @offsets << byte_offset
      @counter.count(0, byte_offset)
    elsif index == 0
      @offsets.unshift(byte_offset)
      @counter.count(0, byte_offset)
    else
      @offsets.insert(index, byte_offset)
      offset = @offsets[index - 1]
      @cache[offset] + @counter.count(offset, byte_offset - offset)
    end
end