Class: Klenod::Runtime::SourceMap::SourceMap

Inherits:
Data
  • Object
show all
Defined in:
lib/klenod/runtime/source_map.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#inputObject (readonly)

Returns the value of attribute input

Returns:

  • (Object)

    the current value of input



23
24
25
# File 'lib/klenod/runtime/source_map.rb', line 23

def input
  @input
end

#marks_by_output_lineObject (readonly)

Returns the value of attribute marks_by_output_line

Returns:

  • (Object)

    the current value of marks_by_output_line



23
24
25
# File 'lib/klenod/runtime/source_map.rb', line 23

def marks_by_output_line
  @marks_by_output_line
end

#outputObject (readonly)

Returns the value of attribute output

Returns:

  • (Object)

    the current value of output



23
24
25
# File 'lib/klenod/runtime/source_map.rb', line 23

def output
  @output
end

Class Method Details

.parse(input, output) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/klenod/runtime/source_map.rb', line 24

def self.parse(input, output)
  marks = {}
  return new(input, output, marks.freeze) unless output.include?(MARK_PREFIX)

  output.each_line.with_index(1) do |line, line_no|
    if (mark = parse_line_mark(line))
      marks[line_no] = mark
    end
  end

  new(input, output, marks.freeze)
end

.parse_line_mark(line) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/klenod/runtime/source_map.rb', line 37

def self.parse_line_mark(line)
  start = line.index(MARK_PREFIX)
  return nil unless start

  index = start + MARK_PREFIX.length
  return nil unless line.getbyte(index) == 58 # :

  index += 1
  line_start = index
  index += 1 while (byte = line.getbyte(index)) && byte >= 48 && byte <= 57
  return nil if index == line_start

  Mark.new(line.byteslice(line_start, index - line_start).to_i)
end

Instance Method Details

#find_original_line_no(output_line_no) ⇒ Object



52
53
54
55
56
57
58
59
60
# File 'lib/klenod/runtime/source_map.rb', line 52

def find_original_line_no(output_line_no)
  # Marks apply until the next mark, so generated code only needs a mark
  # before the expression it came from.
  marks_by_output_line
    .select { |line_no, _mark| line_no <= output_line_no }
    .max_by { |line_no, _mark| line_no }
    &.last
    &.line
end