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.


176
177
178
179
180
181
# File 'lib/ruby_lsp/document.rb', line 176

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


185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/ruby_lsp/document.rb', line 185

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


207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/ruby_lsp/document.rb', line 207

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