class Parse::MapPosition

@example

def pos(line, column, file)
  Parse::Position.new(line, column, file)
end

m = Parse::MapPosition.new
m.map_from(pos(5, 10, "src.c"), pos(3, 2, "src.y"))
m.map_from(pos(30, 5, "src.c"), pos(0, 0, "extra.y"))
p m[pos(1,12,"src.c")]  # src.c:1:12
p m[pos(5,12,"src.c")]  # src.y:3:4
p m[pos(6,10,"src.c")]  # src.y:4:10
p m[pos(30,5,"src.c")]  # extra.y:0:0
p m[pos(40,0,"src.c")]  # extra.y:10:0

Constants

Mapping

@!visibility private

Public Class Methods

new() click to toggle source
# File lib/parse/map_position.rb, line 24
def initialize()
  @mappings = []
end

Public Instance Methods

[](pos1) click to toggle source

See also {#map_from}.

@param [Position] pos1 @return [Position]

# File lib/parse/map_position.rb, line 61
def [](pos1)
  #
  return pos1 if @mappings.empty? or @mappings.first.pos_b.file != pos1.file
  #
  mapping = find_mapping_for pos1
  #
  return pos1 if mapping.nil?
  #
  pos_b, new_pos_b = mapping.pos_b, mapping.new_pos_b
  # new_pos_b.advance(pos1 |-| pos_b)
  if pos1.line == pos_b.line
  then Parse::Position.new(new_pos_b.line, new_pos_b.column + (pos1.column - pos_b.column), new_pos_b.file)
  else Parse::Position.new(new_pos_b.line + (pos1.line - pos_b.line), pos1.column, new_pos_b.file)
  end
end
Also aliased as: call
call(pos1)
Alias for: []
map_from(pos_b, new_pos_b) click to toggle source

Before:

  • m[pos1] == pos2

After:

  • m[pos1] == new_pos_b.advance(pos1 |-| pos_b) if pos1 >= pos_b

  • m[pos1] == pos2 otherwise

Here pos_m |-| pos_n is the number of characters between pos_m and pos_n; p.advance(n) is p advanced by n characters.

This method can not be called with pos_b with different {Position#file}s!

@param [Position] pos_b @param [Position] new_pos_b @return [self]

# File lib/parse/map_position.rb, line 50
def map_from(pos_b, new_pos_b)
  raise "can not call this method with different Position#file (was `#{@mappings.first.pos_b.file}' but `#{pos_b.file}' specified)" if not @mappings.empty? and @mappings.first.pos_b.file != pos_b.file
  pos_b_idx = @mappings.bsearch_index { |mapping| mapping.pos_b >= pos_b } || @mappings.size
  @mappings[pos_b_idx..-1] = [Mapping[pos_b, new_pos_b]]
end

Private Instance Methods

find_mapping_for(pos1) click to toggle source

@return [Mapping, nil] a {Mapping} from +@mappings+ with

{Mapping#pos_b} == max and {Mapping#pos_b} <= pos1;
or nil if there is no such {Mapping}.
# File lib/parse/map_position.rb, line 84
def find_mapping_for pos1
  idx = @mappings.bsearch_index { |mapping| mapping.pos_b >= pos1 }
  return @mappings.last if idx.nil?
  return @mappings[idx] if pos1 == @mappings[idx].pos_b
  return nil if idx == 0
  return @mappings[idx - 1]
end