Class: Ibex::Location
- Inherits:
-
Object
- Object
- Ibex::Location
- Defined in:
- lib/ibex/location.rb
Overview
Immutable source range suitable for lexer tokens and parser diagnostics.
Coordinates are one-based. Byte offsets are optional, zero-based, and half-open. Keeping both forms lets Unicode-aware lexers report human columns without losing an exact source slice.
Instance Attribute Summary collapse
-
#column ⇒ Object
readonly
: Integer.
-
#end_byte ⇒ Object
readonly
: Integer?.
-
#end_column ⇒ Object
readonly
: Integer.
-
#end_line ⇒ Object
readonly
: Integer.
-
#file ⇒ Object
readonly
: String?.
-
#line ⇒ Object
readonly
: Integer.
-
#source_line ⇒ Object
readonly
: String?.
-
#start_byte ⇒ Object
readonly
: Integer?.
Class Method Summary collapse
-
.join(locations) ⇒ Object
Fold a nonempty collection into one covering range.
Instance Method Summary collapse
- #empty? ⇒ Boolean
-
#initialize(line:, column:, file: nil, end_line: nil, end_column: nil, start_byte: nil, end_byte: nil, source_line: nil) ⇒ Location
constructor
A new instance of Location.
-
#join(other) ⇒ Object
Return the smallest range covering both locations.
- #to_h ⇒ Object
Constructor Details
#initialize(line:, column:, file: nil, end_line: nil, end_column: nil, start_byte: nil, end_byte: nil, source_line: nil) ⇒ Location
Returns a new instance of Location.
22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/ibex/location.rb', line 22 def initialize(line:, column:, file: nil, end_line: nil, end_column: nil, start_byte: nil, end_byte: nil, source_line: nil) @file = file&.dup&.freeze @line = positive_coordinate(:line, line) @column = positive_coordinate(:column, column) @end_line = positive_coordinate(:end_line, end_line || line) @end_column = positive_coordinate(:end_column, end_column || column) @start_byte = optional_offset(:start_byte, start_byte) @end_byte = optional_offset(:end_byte, end_byte) @source_line = source_line&.dup&.freeze validate_order! freeze end |
Instance Attribute Details
#column ⇒ Object (readonly)
: Integer
13 14 15 |
# File 'lib/ibex/location.rb', line 13 def column @column end |
#end_byte ⇒ Object (readonly)
: Integer?
17 18 19 |
# File 'lib/ibex/location.rb', line 17 def end_byte @end_byte end |
#end_column ⇒ Object (readonly)
: Integer
15 16 17 |
# File 'lib/ibex/location.rb', line 15 def end_column @end_column end |
#end_line ⇒ Object (readonly)
: Integer
14 15 16 |
# File 'lib/ibex/location.rb', line 14 def end_line @end_line end |
#file ⇒ Object (readonly)
: String?
11 12 13 |
# File 'lib/ibex/location.rb', line 11 def file @file end |
#line ⇒ Object (readonly)
: Integer
12 13 14 |
# File 'lib/ibex/location.rb', line 12 def line @line end |
#source_line ⇒ Object (readonly)
: String?
18 19 20 |
# File 'lib/ibex/location.rb', line 18 def source_line @source_line end |
#start_byte ⇒ Object (readonly)
: Integer?
16 17 18 |
# File 'lib/ibex/location.rb', line 16 def start_byte @start_byte end |
Class Method Details
.join(locations) ⇒ Object
Fold a nonempty collection into one covering range.
53 54 55 56 57 |
# File 'lib/ibex/location.rb', line 53 def self.join(locations) values = locations.to_a first = values.shift || raise(ArgumentError, "locations must not be empty") values.reduce(first) { |combined, location| combined.join(location) } end |
Instance Method Details
#empty? ⇒ Boolean
60 61 62 63 |
# File 'lib/ibex/location.rb', line 60 def empty? @line == @end_line && @column == @end_column && (@start_byte.nil? || @end_byte.nil? || @start_byte == @end_byte) end |
#join(other) ⇒ Object
Return the smallest range covering both locations.
38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/ibex/location.rb', line 38 def join(other) raise ArgumentError, "location files differ" unless file == other.file first = before_or_equal?(self, other) ? self : other ending = before_or_equal_end?(self, other) ? other : self self.class.new( file: file, line: first.line, column: first.column, end_line: ending.end_line, end_column: ending.end_column, start_byte: joined_start_byte(other), end_byte: joined_end_byte(other), source_line: first.source_line ) end |
#to_h ⇒ Object
66 67 68 69 70 71 72 |
# File 'lib/ibex/location.rb', line 66 def to_h { file: @file, line: @line, column: @column, end_line: @end_line, end_column: @end_column, start_byte: @start_byte, end_byte: @end_byte }.compact end |