lib/parser/source/range.rb in parser-2.0.0.pre8 vs lib/parser/source/range.rb in parser-2.0.0

- old
+ new

@@ -1,92 +1,186 @@ module Parser module Source ## + # A range of characters in a particular source buffer. + # + # The range is always exclusive, i.e. a range with `begin_pos` of 3 and + # `end_pos` of 5 will contain the following characters: + # + # example + # ^^ + # + # @!attribute [r] source_buffer + # @return [Parser::Diagnostic::Engine] + # + # @!attribute [r] begin_pos + # @return [Integer] index of the first character in the range + # + # @!attribute [r] end_pos + # @return [Integer] index of the character after the last character in the range + # # @api public # class Range attr_reader :source_buffer attr_reader :begin_pos, :end_pos + ## + # @param [Buffer] source_buffer + # @param [Integer] begin_pos + # @param [Integer] end_pos + # def initialize(source_buffer, begin_pos, end_pos) @source_buffer = source_buffer @begin_pos, @end_pos = begin_pos, end_pos freeze end + ## + # @return [Range] a zero-length range located just before the beginning + # of this range. + # def begin Range.new(@source_buffer, @begin_pos, @begin_pos) end + ## + # @return [Range] a zero-length range located just after the end + # of this range. + # def end Range.new(@source_buffer, @end_pos, @end_pos) end + ## + # @return [Integer] amount of characters included in this range. + # def size @end_pos - @begin_pos end alias length size + ## + # Line number of the beginning of this range. By default, the first line + # of a buffer is 1; as such, line numbers are most commonly one-based. + # + # @see Buffer + # @return [Integer] line number of the beginning of this range. + # def line line, _ = @source_buffer.decompose_position(@begin_pos) line end + ## + # @return [Integer] zero-based column number of the beginning of this range. + # def column _, column = @source_buffer.decompose_position(@begin_pos) column end + ## + # @return [::Range] a range of columns spanned by this range. + # @raise RangeError + # def column_range + if self.begin.line != self.end.line + raise RangeError, "#{self.inspect} spans more than one line" + end + self.begin.column...self.end.column end + ## + # @return [String] a line of source code containing the beginning of this range. + # def source_line @source_buffer.source_line(line) end + ## + # @return [String] all source code covered by this range. + # def source @source_buffer.source[self.begin_pos...self.end_pos] end + ## + # `is?` provides a concise way to compare the source corresponding to this range. + # For example, `r.source == '(' || r.source == 'begin'` is equivalent to + # `r.is?('(', 'begin')`. + # def is?(*what) what.include?(source) end + ## + # @return [Array(Integer)] a set of character indexes contained in this range. + # def to_a (@begin_pos...@end_pos).to_a end + ## + # Composes a GNU/Clang-style string representation of the beginning of this + # range. + # + # For example, for the following range in file `foo.rb`, + # + # def foo + # ^^^ + # + # `to_s` will return `foo.rb:1:5`. + # Note that the column index is one-based. + # + # @return [String] + # def to_s line, column = @source_buffer.decompose_position(@begin_pos) [@source_buffer.name, line, column + 1].join(':') end + ## + # @param [Integer] new_size + # @return [Range] a range beginning at the same point as this range and length `new_size`. + # def resize(new_size) Range.new(@source_buffer, @begin_pos, @begin_pos + new_size) end + ## + # @param [Range] other + # @return [Range] smallest possible range spanning both this range and `other`. + # def join(other) Range.new(@source_buffer, [@begin_pos, other.begin_pos].min, [@end_pos, other.end_pos].max) end + ## + # Compares ranges. + # @return [Boolean] + # def ==(other) other.is_a?(Range) && @source_buffer == other.source_buffer && @begin_pos == other.begin_pos && @end_pos == other.end_pos end + ## + # @return [String] a human-readable representation of this range. + # def inspect - "#<Source::Range #{@source_buffer.name} #{@begin_pos}...#{@end_pos}>" + "#<Parser::Source::Range #{@source_buffer.name} #{@begin_pos}...#{@end_pos}>" end end end end