Class: Shirobai::SourceOffsets

Inherits:
Object
  • Object
show all
Defined in:
lib/shirobai/source_offsets.rb

Overview

Converts the BYTE offsets Rust reports (prism) into the CHARACTER offsets ‘Parser::Source::Range` indexes the buffer with. On an ASCII-only source the two coincide and `#[]` returns its argument unchanged (`ascii_only?` is a cached coderange lookup, so the fast path costs one predicate per offset); on a non-ASCII source each distinct offset is converted once via `byteslice(0, offset).length` (O(offset), memoized — offenses are rare and repeat offsets, so the naive prefix count beats maintaining a table).

‘.for` memoizes the instance by source identity (`equal?`, the same single-slot scheme as `Dispatch`): cops run file by file, so every cop on the current file shares one converter (and its memo), while the autocorrect loop’s freshly built source naturally gets a new one.

NOTE for wrapper authors: convert ONLY what feeds ‘Parser::Source::Range` (or other char-indexed Ruby APIs). Values handed BACK to Rust (e.g. `IndentationWidth`’s accumulated prior correction ranges) must stay bytes.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source) ⇒ SourceOffsets

Returns a new instance of SourceOffsets.



30
31
32
33
34
# File 'lib/shirobai/source_offsets.rb', line 30

def initialize(source)
  @source = source
  @ascii = source.ascii_only?
  @chars = nil
end

Class Method Details

.for(source) ⇒ Object



22
23
24
25
26
27
# File 'lib/shirobai/source_offsets.rb', line 22

def for(source)
  return @cached if defined?(@cached_source) && @cached_source.equal?(source)

  @cached_source = source
  @cached = new(source)
end

Instance Method Details

#[](byte_offset) ⇒ Object

The character offset for prism’s ‘byte_offset` into this source.



37
38
39
40
41
# File 'lib/shirobai/source_offsets.rb', line 37

def [](byte_offset)
  return byte_offset if @ascii

  (@chars ||= {})[byte_offset] ||= @source.byteslice(0, byte_offset).length
end