123456789_123456789_123456789_123456789_123456789_

Class: Prism::Source

Relationships & Source Files
Inherits: Object
Defined in: lib/prism/parse_result.rb,
prism/extension.c

Overview

This represents a source of Ruby code that has been parsed. It is used in conjunction with locations to allow them to resolve line numbers and source ranges.

Class Method Summary

Instance Attribute Summary

  • #offsets readonly

    The list of newline byte offsets in the source code.

  • #source readonly

    The source code that this source object represents.

  • #start_line rw

    The line number where this source starts.

Instance Method Summary

Constructor Details

.new(source, start_line = 1, offsets = compute_offsets(source)) ⇒ Source

Create a new source object with the given source code and newline byte offsets. If no newline byte offsets are given, they will be computed from the source code.

[ GitHub ]

  
# File 'lib/prism/parse_result.rb', line 20

def initialize(source, start_line = 1, offsets = compute_offsets(source))
  @source = source
  @start_line = start_line
  @offsets = offsets
end

Instance Attribute Details

#offsets (readonly)

The list of newline byte offsets in the source code.

[ GitHub ]

  
# File 'lib/prism/parse_result.rb', line 15

attr_reader :offsets

#source (readonly)

The source code that this source object represents.

[ GitHub ]

  
# File 'lib/prism/parse_result.rb', line 9

attr_reader :source

#start_line (rw)

The line number where this source starts.

[ GitHub ]

  
# File 'lib/prism/parse_result.rb', line 12

attr_accessor :start_line

Instance Method Details

#character_column(byte_offset)

Return the column number in characters for the given byte offset.

[ GitHub ]

  
# File 'lib/prism/parse_result.rb', line 55

def character_column(byte_offset)
  character_offset(byte_offset) - character_offset(line_start(byte_offset))
end

#character_offset(byte_offset)

Return the character offset for the given byte offset.

[ GitHub ]

  
# File 'lib/prism/parse_result.rb', line 50

def character_offset(byte_offset)
  source.byteslice(0, byte_offset).length
end

#column(byte_offset)

Return the column number for the given byte offset.

[ GitHub ]

  
# File 'lib/prism/parse_result.rb', line 45

def column(byte_offset)
  byte_offset - line_start(byte_offset)
end

#compute_offsets(code) (private)

Find all of the newlines in the source code and return their byte offsets from the start of the string an array.

[ GitHub ]

  
# File 'lib/prism/parse_result.rb', line 83

def compute_offsets(code)
  offsets = [0]
  code.b.scan("\n") { offsets << $~.end(0) }
  offsets
end

#find_line(byte_offset) (private)

Binary search through the offsets to find the line number for the given byte offset.

[ GitHub ]

  
# File 'lib/prism/parse_result.rb', line 63

def find_line(byte_offset)
  left = 0
  right = offsets.length - 1

  while left <= right
    mid = left + (right - left) / 2
    return mid if offsets[mid] == byte_offset

    if offsets[mid] < byte_offset
      left = mid + 1
    else
      right = mid - 1
    end
  end

  left - 1
end

#line(byte_offset)

Binary search through the offsets to find the line number for the given byte offset.

[ GitHub ]

  
# File 'lib/prism/parse_result.rb', line 34

def line(byte_offset)
  start_line + find_line(byte_offset)
end

#line_start(byte_offset)

Return the byte offset of the start of the line corresponding to the given byte offset.

[ GitHub ]

  
# File 'lib/prism/parse_result.rb', line 40

def line_start(byte_offset)
  offsets[find_line(byte_offset)]
end

#slice(byte_offset, length)

Perform a byteslice on the source code using the given byte offset and byte length.

[ GitHub ]

  
# File 'lib/prism/parse_result.rb', line 28

def slice(byte_offset, length)
  source.byteslice(byte_offset, length)
end