Class: RubyLsp::Document::Scanner

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/ruby_lsp/document.rb

Constant Summary collapse

LINE_BREAK =
T.let(0x0A, Integer)
SURROGATE_PAIR_START =

After character 0xFFFF, UTF-16 considers characters to have length 2 and we have to account for that

T.let(0xFFFF, Integer)

Instance Method Summary collapse

Constructor Details

#initialize(source, encoding) ⇒ Scanner

Returns a new instance of Scanner.



187
188
189
190
191
192
# File 'lib/ruby_lsp/document.rb', line 187

def initialize(source, encoding)
  @current_line = T.let(0, Integer)
  @pos = T.let(0, Integer)
  @source = T.let(source.codepoints, T::Array[Integer])
  @encoding = encoding
end

Instance Method Details

#find_char_position(position) ⇒ Object



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/ruby_lsp/document.rb', line 196

def find_char_position(position)
  # Find the character index for the beginning of the requested line
  until @current_line == position[:line]
    @pos += 1 until LINE_BREAK == @source[@pos]
    @pos += 1
    @current_line += 1
  end

  # The final position is the beginning of the line plus the requested column. If the encoding is UTF-16, we also
  # need to adjust for surrogate pairs
  requested_position = @pos + position[:character]

  if @encoding == Constant::PositionEncodingKind::UTF16
    requested_position -= utf_16_character_position_correction(@pos, requested_position)
  end

  requested_position
end

#utf_16_character_position_correction(current_position, requested_position) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/ruby_lsp/document.rb', line 218

def utf_16_character_position_correction(current_position, requested_position)
  utf16_unicode_correction = 0

  until current_position == requested_position
    codepoint = @source[current_position]
    utf16_unicode_correction += 1 if codepoint && codepoint > SURROGATE_PAIR_START

    current_position += 1
  end

  utf16_unicode_correction
end